所以,我一直在编写代码从文件中读取数据集并将其分离出来进行分析。
所讨论的数据从.dat文件中读取,看起来像这样:
14 HO2 O3 OH O2 O2
15 HO2 HO2 H2O2 O2
16 H2O2 OH HO2 H2O
17 O O O2
18 O O2 O3
19 O O3 O2 O2
我写的代码是这样的:
edge_data=np.genfromtxt('Early_earth_reaction.dat', dtype = str,
missing_values=True, filling_values=bool)
我的计划是,然后运行数据集中的值,并从它们构建一个配对列表。
edge_list=[]
for i in range(360):
edge_list.append((edge_data[i,0],edge_data[i,2]))
edge_list.append((edge_data[i,1],edge_data[i,2]))
print edge_data[i,0]
if edge_data[i,3] != None:
edge_list.append((edge_data[i,0],edge_data[i,3]))
edge_list.append((edge_data[i,1],edge_data[i,3]))
if edge_data[i,4]!= None:
edge_list.append((edge_data[i,0],edge_data[i,4]))
edge_list.append((edge_data[i,1,edge_data[i,4]))
但是,在运行它时,我得到错误消息
File "read_early_earth.py", line 52, in main
edge_data=np.genfromtxt('Early_earth_reaction.dat', dtype = str,
usecols=(1,2,3,4,5), missing_values=True, filling_values=bool)
File "/usr/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 1667,
in genfromtxt
raise ValueError(errmsg)
ValueError: Some errors were detected !
Line #6 (got 4 columns instead of 5)
Line #14 (got 6 columns instead of 5)
Line #17 (got 4 columns instead of 5)
等等。据我所知,发生这种情况是因为有些行中并非所有列都有值,这显然会引发numpy for循环。
在numpy中有解决这个问题的方法吗?或者,是否有其他方法来完成这项任务?我知道,更糟糕的是,我可以折磨一些正则表达式来完成这项工作,但如果可能的话,我更喜欢一种更有效的方法。
谢谢!
看起来您已经阅读了genfromtxt
关于缺失值的内容。它有没有提到分隔符的使用?
我认为它可以处理像
这样的缺失值。'one, 1, 234.4, , ,'
'two, 3, , 4, 5'
,但当分隔符是默认的'空白'时,它不能。读取一行后的第一步是
strings = line.split(delimiter)
和对象,如果len(strings)
与初始目标不匹配。显然,它不会尝试猜测您想要填充n-len(strings)
缺失值的行。
想到的选项:
试着熊猫;猜测你的意图可能会更困难
编写自己的阅读器。熊猫是编译的;
genfromtxt
是纯numpy Python。它逐行读取文件,分割和转换字段,并将列表附加到主列表。它在最后将列表的列表转换为数组。你自己的阅读器也应该同样高效。预处理文件以添加缺失的值或更改分隔符。
genfromtxt
接受任何输入行。因此,它与字符串列表、生成修改行的文件读取器等一起工作。这可能是最简单的。def foo (astr):str = astr.split ()如果len (str) & lt; 6:str。扩展([b '] * (6-len (str)))返回b ', ' . join (str)
模拟字符串列表(在Py3中):
In [139]: txt=b"""14 HO2 O3 OH O2 O2
...: 15 HO2 HO2 H2O2 O2
...: 16 H2O2 OH HO2 H2O
...: 17 O O O2
...: 18 O O2 O3
...: 19 O O3 O2 O2""".splitlines()
In [140]: [foo(l) for l in txt]
Out[140]:
[b'14,HO2,O3,OH,O2,O2',
b'15,HO2,HO2,H2O2,O2, ',
b'16,H2O2,OH,HO2,H2O, ',
b'17,O,O,O2, , ',
b'18,O,O2,O3, , ',
b'19,O,O3,O2,O2, ']
In [141]: np.genfromtxt([foo(l) for l in txt], dtype=None, delimiter=',')
Out[141]:
array([(14, b'HO2', b'O3', b'OH', b'O2', b'O2'),
(15, b'HO2', b'HO2', b'H2O2', b'O2', b''),
(16, b'H2O2', b'OH', b'HO2', b'H2O', b''),
(17, b'O', b'O', b'O2', b' ', b''),
(18, b'O', b'O2', b'O3', b' ', b''),
(19, b'O', b'O3', b'O2', b'O2', b'')],
dtype=[('f0', '<i4'), ('f1', 'S4'), ('f2', 'S3'), ('f3', 'S4'), ('f4', 'S3'), ('f5', 'S2')])
看起来您的数据在恰好10个字符的字段中很好地对齐。如果总是这样,您可以通过在delimiter
参数中指定字段宽度的顺序来告诉genfromtxt
要使用的字段宽度。
下面是一个例子。
首先,你的数据文件:In [20]: !cat reaction.dat
14 HO2 O3 OH O2 O2
15 HO2 HO2 H2O2 O2
16 H2O2 OH HO2 H2O
17 O O O2
18 O O2 O3
19 O O3 O2 O2
为方便起见,我将在这里定义字段的数量和字段的宽度。(一般来说,没有必要所有的字段都有相同的宽度。)
In [21]: numfields = 6
In [22]: fieldwidth = 10
通过传递参数delimiter=(10, 10, 10, 10, 10, 10)
:
genfromtxt
数据是固定宽度列In [23]: data = genfromtxt('reaction.dat', dtype='S%d' % fieldwidth, delimiter=(fieldwidth,)*numfields)
结果如下。注意,"missing"字段是空字符串。还要注意,非空字段包括空白,每行中的最后一个非空字段包括换行字符:
In [24]: data
Out[24]:
array([[b'14 ', b'HO2 ', b'O3 ', b'OH ',
b'O2 ', b'O2n'],
[b'15 ', b'HO2 ', b'HO2 ', b'H2O2 ',
b'O2n', b''],
[b'16 ', b'H2O2 ', b'OH ', b'HO2 ',
b'H2On', b''],
[b'17 ', b'O ', b'O ', b'O2n', b'', b''],
[b'18 ', b'O ', b'O2 ', b'O3n', b'', b''],
[b'19 ', b'O ', b'O3 ', b'O2 ',
b'O2n', b'']],
dtype='|S10')
In [25]: data[1]
Out[25]:
array([b'15 ', b'HO2 ', b'HO2 ', b'H2O2 ', b'O2n',
b''],
dtype='|S10')
我们可以在第二步中清理字符串,或者我们可以让genfromtxt
为每个字段提供一个转换器,简单地从字段中删除空白:
In [26]: data = genfromtxt('reaction.dat', dtype='S%d' % fieldwidth, delimiter=(fieldwidth,)*numfields, converters={k: lambda s: s.
...: strip() for k in range(numfields)})
In [27]: data
Out[27]:
array([[b'14', b'HO2', b'O3', b'OH', b'O2', b'O2'],
[b'15', b'HO2', b'HO2', b'H2O2', b'O2', b''],
[b'16', b'H2O2', b'OH', b'HO2', b'H2O', b''],
[b'17', b'O', b'O', b'O2', b'', b''],
[b'18', b'O', b'O2', b'O3', b'', b''],
[b'19', b'O', b'O3', b'O2', b'O2', b'']],
dtype='|S10')
In [28]: data[:,0]
Out[28]:
array([b'14', b'15', b'16', b'17', b'18', b'19'],
dtype='|S10')
In [29]: data[:,5]
Out[29]:
array([b'O2', b'', b'', b'', b'', b''],
dtype='|S10')