【问题标题】:Numpy loadtxt: ValueError: Wrong number of columnsNumpy loadtxt:ValueError:错误的列数
【发布时间】:2016-06-22 16:00:00
【问题描述】:

文件 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 中类似的东西将不胜感激。

【问题讨论】:

  • 多余的应该怎么办?
  • 你想如何存储它们?你能写下预期的输出吗?
  • @GM,我认为使用 loadtxt 无法实现您想要的,您可以使用带有列表的 python 来实现
  • 或者功能上的arr = list(map(str.split, f)),它会给你['a', '45'], ['b', '45', '55'], ['c', '66']]
  • with open('TEST.txt') as f:arr = list(map(str.split, f))

标签: python python-3.x pandas numpy


【解决方案1】:

试试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 可以很容易地为每列构造一个具有不同 dtype 的结构化数组。请注意,这样的数组是 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')])

【讨论】:

  • hmm,我刚刚在数据格式 1,2,3;1,2;1,2,3,4 上尝试了 genfromtxt(),但它给了我错误 Line #3(改为 4 列6)
  • 是的,如果列数不同,它会这样做。确保您使用了正确的分隔符。
  • 是的,添加分隔符有帮助,但它会重塑它。有没有办法保持原始格式?
  • 格式良好的 csv 只有一种可能的形状。好吧,如果您指定复合 dtype 和结构化数组,则为两个。在没有看到您文件的一部分的情况下,我不知道它应该具有什么形状和 dtype。评论不是调试这个的地方。
【解决方案2】:

如果您有可变数量的列,则无法定义正确的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']

【讨论】:

    【解决方案3】:

    如果您希望所有行具有相同数量的列,但有些缺少值,您可以使用 pandas 轻松实现。但是你必须知道总列数。

    import pandas as pd
    pd.read_csv('foo.txt', sep='\t', names=['col_a','col_b'])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-01
      • 2015-12-01
      • 2013-02-15
      • 1970-01-01
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多