numpy.genfromtext - ValueError- Line #(得到n列而不是m列)



所以,我一直在编写代码从文件中读取数据集并将其分离出来进行分析。

所讨论的数据从.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')

相关内容

  • 没有找到相关文章

最新更新