所以,我一直在编写代码来读取文件中的数据集并将其分开进行分析。
有问题的数据是从.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。
在numpy中有解决方法吗?或者,还有另一种方法可以完成这项任务吗?我知道,更糟糕的是,我可以折磨一些正则表达式来完成这项工作,但我更喜欢一种方法,如果可能的话,它会更有效率。
谢谢!
答案 0 :(得分:2)
您似乎已经阅读了有关缺失值的genfromtxt
。它是否说明了分隔符的使用?
我认为它可以用
这样的行来处理缺失值'one, 1, 234.4, , ,'
'two, 3, , 4, 5'
但是当分隔符是默认的'白色空间'它不能。阅读一行后的第一步是
strings = line.split(delimiter)
如果len(strings)
与初始目标不匹配,则为对象。显然,它不会猜测你想填充n-len(strings)
缺少值的行。
想到的选项:
尝试熊猫;它可能会更加努力地猜测你的意图
写自己的读者。熊猫编译; genfromtxt
是简单的Python。它逐行读取文件,拆分并转换字段,并将列表附加到主列表。它最后将该列表列表转换为数组。你自己的读者应该同样有效率。
预处理文件以添加缺失值或更改分隔符。 genfromtxt
接受任何为其提供线条的内容。所以它适用于字符串列表,产生修改行的文件阅读器等。这可能是最简单的。
def foo(astr): 个STR = astr.split() 如果len(strs)< 6: strs.extend([b''] *(6-len(strs))) 返回b',' .join(strs)
使用字符串列表进行模拟(在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')])
答案 1 :(得分:0)
看起来您的数据在10个字符的字段中很好地对齐。如果总是如此,您可以通过在genfromtxt
参数中指定字段宽度序列来告诉delimiter
要使用的字段宽度。
以下是一个例子。
首先,您的数据文件:
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
通过传递参数genfromtxt
告诉delimiter=(10, 10, 10, 10, 10, 10)
数据是固定宽度列:
In [23]: data = genfromtxt('reaction.dat', dtype='S%d' % fieldwidth, delimiter=(fieldwidth,)*numfields)
这是结果。请注意&#34;缺少&#34;字段是空字符串。另请注意,非空字段包括空格,每行中的最后一个非空字段包含换行符:
In [24]: data
Out[24]:
array([[b'14 ', b'HO2 ', b'O3 ', b'OH ',
b'O2 ', b'O2\n'],
[b'15 ', b'HO2 ', b'HO2 ', b'H2O2 ',
b'O2\n', b''],
[b'16 ', b'H2O2 ', b'OH ', b'HO2 ',
b'H2O\n', b''],
[b'17 ', b'O ', b'O ', b'O2\n', b'', b''],
[b'18 ', b'O ', b'O2 ', b'O3\n', b'', b''],
[b'19 ', b'O ', b'O3 ', b'O2 ',
b'O2\n', b'']],
dtype='|S10')
In [25]: data[1]
Out[25]:
array([b'15 ', b'HO2 ', b'HO2 ', b'H2O2 ', b'O2\n',
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')