将unicode元素读入​​numpy数组

时间:2011-06-16 16:30:45

标签: python unicode numpy

考虑一个名为“new.txt”的文本文件,其中包含以下元素:

μm
∂r
∆λ

在Python 2.7中,我可以通过输入以下内容来读取文件:

>>> import codecs
>>> f = codecs.open('new.txt', encoding='utf-8')
>>> lines = [line.strip() for line in f2.readlines()]
>>> lines
[u'\u03bcm', u'\u2202r', u'\u2206\u03bb']
>>> print lines[0]
μm

到目前为止一切顺利。我可以通过以下方式轻松地将此列表转换为numpy数组:

>>> import numpy as np
>>> arr = np.array(lines)
>>> arr
array([u'\u03bcm', u'\u2202r', u'\u2206\u03bb'], 
      dtype='<U2')

问题是,我无法通过numpy的loadtxt函数直接读取此文件:

>>> np.loadtxt('new.txt', dtype=np.unicode_)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/numpy/lib/npyio.py", line 805, in loadtxt
    X = np.array(X, dtype)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)

直接将此文件读入numpy的正确方法是什么?

感谢。

2 个答案:

答案 0 :(得分:10)

在内存中,unicode字符串表示为UCS-2UCS-4,具体取决于Python解释器的编译方式。您的文件以UTF-8编码,因此您需要在将其映射到NumPy数组之前对其进行重新编码。 loadtxt()无法为您进行重新编码 - 毕竟NumPy主要针对数值数组。

假设每一行都有相同数量的字符,您还可以使用效率更高的变体

s = codecs.open("new.txt", encoding="utf-8").read()
arr = numpy.frombuffer(s, dtype="<U3")

这将包括字符串中的换行符。要不包含它们,请使用

arr = numpy.frombuffer(s.replace("\n", ""), dtype="<U2")

修改:如果您的文件行长度不同,并且您想避开中间列表,则可以使用

arr = numpy.fromiter(codecs.open("new.txt", encoding="utf-8"), dtype="<U2")

我不确定这是否会在内部创建一些临时列表。

答案 1 :(得分:2)

如果要使用loadtxt,可以先加载原始字节数组然后解码:

data = np.loadtxt('foo.txt', dtype='S8')
unicode_data = data.view(np.chararray).decode('utf-8')

或指定转换器进行解码:

data = np.loadtxt('foo.txt', converters={0: lambda x: unicode(x, 'utf-8')}, dtype='U2')

然而,在Sven的回答中使用fromiter可能比loadtxt更有效。