Numpy loadtxt:ValueError:列数错误

2024-06-07 17:17:40 发布

您现在位置:Python中文网/ 问答频道 /正文

文件TEST.txt的结构如下:

a   45
b   45  55
c   66

当我试图打开它时:

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

我有以下错误:

ValueError: Wrong number of columns at line 2

很明显,这是因为第二行有三列而不是两列,但是使用文档我找不到问题的答案。

我能把所有的数据保存在一个数组中吗?

在Matlab中,我可以做如下事情:

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

在Python中类似的东西也会受到重视。


Tags: 文件testimportnumpytxtas错误np
3条回答

如果希望所有行具有相同的列数,但有些行缺少值,则可以使用pandas轻松完成此操作。但是你必须知道列的总数。

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

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

尝试np.genfromtxt。它处理丢失的值;loadtxt不处理。比较他们的文件。

当分隔符为空白时,缺少值可能会很棘手,但是使用制表符应该没问题。如果仍然存在问题,请使用,分隔符对其进行测试。

哦-你还需要额外的分隔符

例如

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

loadtxtgenfromtxt都接受逐行传递txt的任何iterable。所以一件简单的事情就是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”(用于baby和me)。

对于字符串,这是过分的;但是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')])

相关问题 更多 >

    热门问题