1

我有一个来自 QuickDAQ 的 tsv 文件,其中包含三列 200 000 个值,我想将它们导入 numpy。问题是 genfromtxt 似乎错过了最后一行。就我所见,这条线并没有什么特别之处:

...
0,00232172012329102     0,0198968648910522      0,0049593448638916
0,00411009788513184     0,0142784118652344      0,00339150428771973
0,00499653816223145     0,00666630268096924     0,00308072566986084

不太有效的代码示例:

In [245]: import numpy as np

In [246]: oompa = np.genfromtxt('C_20k_73_2.tsv',delimiter='\t',usecols=(0,1,2),unpack=True,skip_header=13,dtype=str)

In [248]: oompa[1]
Out[248]: 
array(['-0,00884926319122314', '-0,00379836559295654',
   '0,000106096267700195', ..., '0,0259654521942139',
   '0,0198968648910522', '0,0142784118652344'], 
  dtype='<U21')

该文件有 Windows 样式的换行符,我尝试在 vi 中删除这些换行符,但没有任何区别。什么可能导致 genfromtxt 出现这种行为,如何处理,最好不手动编辑 tsv 文件?

4

1 回答 1

1

好吧,该文件似乎有一些只有制表符的行。我很惊讶np.genfromtxt没有提出一个ValueError。防止该问题的一种方法是删除那些空的制表符行。另一个可能是invalid_raise=False在调用中使用参数np.genfromtxt

oompa = np.genfromtxt('C_20k_73_2.tsv',delimiter='\t',
            usecols=(0,1,2),unpack=True,skip_header=13,
            dtype=str, invalid_raise=False)

np.genfromtxt这将跳过与预期解析的列数不一致的行。


如果文件不太长,查看文件最后几行的简单方法是

print(open(filename, 'rb').read().splitlines()[:-3])

由于这会打印一个列表,因此您repr无需repr直接调用即可获得列表中的项目。这repr可以很容易地查看制表符和行尾字符的位置。

通过检查repr成功解析的最后一行np.genfromtxt与跳过的第一行相比,您应该能够发现导致问题的中断模式。


如果文件很长,可以使用打印最后几行

import collections
lines = collections.deque(maxlen=2)
with open('data', 'rb') as f:
    lines.extend(f)
print(list(lines))

问题open(filename, 'rb').read().splitlines()在于它将整个文件读入内存,然后将巨大的字符串拆分成一个巨大的列表。当文件太大时,这可能会导致 MemoryError。具有最大数量的deque元素,因此只要行本身不太长,就可以防止出现问题。

于 2014-04-15T12:08:45.370 回答