Numpy loadtxt:ValueError:错误的列数

新手上路,请多包涵

文件 TEST.txt 的结构如下:

 a   45
b   45  55
c   66

当我尝试打开它时:

 import numpy as np
a= np.loadtxt(r'TEST.txt',delimiter='\t',dtype=str)

我收到以下错误:

ValueError:第 2 行的列数错误

这显然是由于第二行有三列而不是两列,但我无法使用文档找到我的问题的答案。

无论如何我可以修复它,将所有数据保存到一个数组中吗?

在 Matlab 中,我可以做类似的事情:

 a=textscan(fopen('TEST.txt'),'%s%s%s');

Python 中类似的东西会受到赞赏。

原文由 G M 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 514
2 个回答

尝试 np.genfromtxt 。它处理缺失值; loadtxt 没有。比较他们的文档。

当分隔符是空格时,缺失值可能会很棘手,但使用制表符应该没问题。如果还有问题,用 , 分隔符测试一下。

哎呀 - 你仍然需要额外的分隔符

例如。

 a, 34,
b, 43, 34
c, 34

loadtxtgenfromtxt 都接受逐行传递 txt 的任何迭代。所以一个简单的事情是 readlines ,调整具有缺失值和分隔符的行,并将该行列表传递给加载程序。或者你可以把它写成一个“过滤器”或生成器。这种方法已在许多先前的 SO 问题中进行了描述。

 In [36]: txt=b"""a\t45\t\nb\t45\t55\nc\t66\t""".splitlines()
In [37]: txt
Out[37]: [b'a\t45\t', b'b\t45\t55', b'c\t66\t']
In [38]: np.genfromtxt(txt,delimiter='\t',dtype=str)
Out[38]:
array([['a', '45', ''],
       ['b', '45', '55'],
       ['c', '66', '']],
      dtype='<U2')

我使用的是 Python3,因此字节字符串标有“b”(用于婴儿和我)。

对于字符串,这太过分了;但是 genfromtxt 可以很容易地为每列构造一个具有不同数据类型的结构化数组。请注意,这样的数组是 1d,具有命名字段 - 而不是编号列。

 In [50]: np.genfromtxt(txt,delimiter='\t',dtype=None)
Out[50]:
array([(b'a', 45, -1), (b'b', 45, 55), (b'c', 66, -1)],
      dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4')])

填充行我可以定义一个函数,如:

 def foo(astr,delimiter=b',',cnt=3,fill=b' '):
    c = astr.strip().split(delimiter)
    c.extend([fill]*cnt)
    return delimiter.join(c[:cnt])

并将其用作:

 In [85]: txt=b"""a\t45\nb\t45\t55\nc\t66""".splitlines()

In [87]: txt1=[foo(txt[0],b'\t',3,b'0') for t in txt]
In [88]: txt1
Out[88]: [b'a\t45\t0', b'a\t45\t0', b'a\t45\t0']
In [89]: np.genfromtxt(txt1,delimiter='\t',dtype=None)
Out[89]:
array([(b'a', 45, 0), (b'a', 45, 0), (b'a', 45, 0)],
      dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4')])

原文由 hpaulj 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果列数可变,则无法定义正确的 np.array 形状。如果你想将它们存储在 np.array 尝试:

 import numpy as np
a = np.loadtxt(r'TEST.txt', delimiter='\n', dtype=str)

现在 aarray(['a 45', 'b 45 55', 'c 66'])

但在这种情况下最好是一个列表:

 with open(r'TEST.txt') as f:
    a = f.read().splitlines()

现在 a 是一个列表 ['a 45', 'b 45 55', 'c 66']

原文由 Francesco Nazzaro 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题