Python3中使用numpy genfromtxt时出现的问题

5

我正在尝试使用Python3中的genfromtxt来读取一个包含字符串和数字的简单csv文件。例如,像这样的内容(以下称为“test.csv”):

1,a
2,b
3,c

使用Python2,以下内容可以正常工作:

import numpy
data=numpy.genfromtxt("test.csv", delimiter=",", dtype=None)
# Now data is something like [(1, 'a') (2, 'b') (3, 'c')]

在Python3中,相同的代码返回[(1,b'a')(2,b'b')(3,b'c')] 。这在某种程度上是预期的,因为Python3以不同的方式读取文件。因此,我使用转换器对字符串进行解码:
decodef = lambda x: x.decode("utf-8")
data=numpy.genfromtxt("test.csv", delimiter=",", dtype="f8,S8", converters={1: decodef})

这段代码在Python2中可以运行,但是在Python3中无法运行(输出相同的[(1, b'a') (2, b'b') (3, b'c')]结果)。然而,如果在Python3中使用上述代码只读取一列,则可以正常运行:
data=numpy.genfromtxt("test.csv", delimiter=",", usecols=(1,), dtype="S8", converters={1: decodef})

输出的字符串是已经按预期解码为['a' 'b' 'c']。我还尝试将文件作为'rb'模式的open输出,如此链接所建议的那样,但没有改进。为什么只读取一个列时转换器可以工作,而读取两个列时不能工作?请问您能否建议我在Python3中正确使用genfromtxt的方法?我做错了什么吗?谢谢!

这里的问题是什么? - wim
@wim 已编辑。现在问题应该更清晰了。 - Alessandro
我也遇到了同样的问题。一开始我对使用字节b'文字的方式感到非常困惑,而不是预期的字符串。我的CSV文件有两列:情感值为0或1;以及文本(UTF-16编码)。使用这种解码方法分别处理这些列是可行的。 - chri3g91
3个回答

9
我的问题的答案是使用dtype来处理Unicode字符串(例如,U2)。
感谢E.Kehler的答案,我找到了解决方案。 如果我在dtype定义中使用str代替S8,那么第二列的输出为空:
numpy.genfromtxt("test.csv", delimiter=",", dtype='f8,str')

输出结果如下:
array([(1.0, ''), (2.0, ''), (3.0, '')], dtype=[('f0', '<f16'), ('f1', '<U0')])

这启示我,解决我的问题的正确dtype是一个Unicode字符串:
numpy.genfromtxt("test.csv", delimiter=",", dtype='f8,U2')

这将提供预期的输出:

array([(1.0, 'a'), (2.0, 'b'), (3.0, 'c')], dtype=[('f0', '<f16'), ('f1', '<U2')])

有用的信息也可以在numpy数据类型文档页面中找到。


1
在Python 3中,使用

dtype="S8"

(或任何"S#"的变体)在NumPy的genfromtxt中会产生一个字节字符串。为了避免这种情况并获得一个传统的字符串,请改用

dtype=str


谢谢你的回答。然而,它没有解决我的问题,因为使用 strnumpy.genfromtxt("test.csv", delimiter=",", dtype='f8,str') 的输出在第二列中给出了一个空字符串(和一个 dtype <U0)。这帮助我找到了答案(请参见我的答案)。 - Alessandro

0
training = np.genfromtxt('twitter_train.csv', delimiter=',', usecols=(0,1), dtype='U')

在我的情况下,第一列包含一个情感值,可以是0或1,第二列是一个由许多字符组成的字符串,表示这个例子中的推文。 dtype='U' 移除了包含b'的内容。
所以在你的情况下,应该是: data=numpy.genfromtxt("test.csv", delimiter=",", dtype='U')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接