2011-06-16 11 views
9

考慮稱爲文本文件 「new.txt」 含有以下元素:雷丁的unicode元素注入numpy的陣列

μ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?

謝謝。

回答

8

在內存中,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

+1 - 但是一個提示:你可以將一個打開的文件直接傳遞給'loadtxt',對於我來說,用'codecs.open'打開文件並傳遞給'loadtxt'解決了這個問題。或者相當類似的問題,因爲我的'loadtxt'對utf-8文件沒有問題! – senderle 2011-06-16 16:58:59

+0

@senderle:奇怪 - 不適合我。我在這裏使用NumPy 1.5.1 - 也許這很重要。 – 2011-06-16 17:23:28

+0

這與使用numpy Python 3端口有什麼關係?我仍然在我的numpy中使用Python 2.7下的UnicodeEncodeError。 – 2011-06-16 17:28:53

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') 

然而,使用fromiter作爲在斯文的回答可能會比loadtxt更有效。