将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 个回答
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
更有效。
10
在内存中,unicode字符串的表示方式有两种,分别是UCS-2和UCS-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")
不过我不确定这样做内部是否会创建一些临时列表。