2017-03-16 29 views
1

我試圖確保一些相對簡單的Python 2模塊與Python 3兼容。我目前有一個數據文件,爲了MWE的目的,看起來像numpy.loadtxt無法讀取Python中的int 3

n 
0 

下面的代碼片段正常工作與Python 2.7,這基本上是一個變通方法來得到這樣genfromtxtnames=True行爲在這兩個的Python 2.7和3.5相同的代碼。

import numpy as np 
with open('bad_int.data', 'rb') as f: lines = f.readlines() 
data = np.loadtxt(lines[1:2], dtype=[('n', int)]) 

使用Python 3.5,我得到的錯誤

Traceback (most recent call last): 
    File "bad_int3.py", line 5, in <module> 
    data = np.loadtxt(lines[1:2], dtype=[('n',int)]) 
    File "/usr/lib64/python3.5/site-packages/numpy/lib/npyio.py", line 938, in loadtxt 
    X = np.array(X, dtype) 
ValueError: invalid literal for int() with base 10: "b'0'" 

我知道有裝載這樣的文件的其他方式,但我目前勢必切片增長線的文件,因爲它具有不止一個數組。我試圖找出領先的b意味着什麼(二進制?),但沒有運氣。那麼如何在Python 2.7和3.5中讀取這種數據而不會出現這個錯誤呢?

編輯

我剛剛注意到,如果有一個以上的領域,一切工作正常。因此,例如,如果數據更改爲

n m 
0 0 

和最後一行

data = np.loadtxt(lines[1:2], dtype=[('n', int), ('m', int)]) 

那麼一切都完美地工作在Python 2.7和3.5。

+0

你確定你的輸入文件? –

+0

我剛剛使用Emacs創建了自己的MWE示例。我也試着用'echo -e「n \ n0」> bad_int.data'將它發送到一個文件。 – Warrick

+0

理想情況下,我想自動推斷該字段的名稱是來自該文件的'n',但我可以很容易地做到這一點。所以只需讀取'0'即可。但數據可能不在文件的開頭,也不一定是文件的結尾。 – Warrick

回答

3

在PY3你需要以二進制方式打開文件:

with open('data', 'rb') as f: 
    lines = f.readlines() 
    data = np.loadtxt(lines[1:2], dtype=[('n',int)]) 

loadtxt(和genfromtxt)用字節串操作。所以如果他們自己打開文件,他們使用rb

您也可以嘗試:

data = np.loadtxt('data', skiprows=1, dtype=[('n',int)]) 

領先b表示字節字符串。 Py3字符串默認是unicode。


In [99]: txt=b"""n 
    ...: 0 
    ...: 1""" 
In [100]: np.loadtxt(txt.splitlines()[1:], dtype=int) 
Out[100]: array([0, 1]) 

但與D型

In [101]: dt=np.dtype([('n',int)]) 
In [102]: np.loadtxt(txt.splitlines()[1:], dtype=dt) 
... 
ValueError: invalid literal for int() with base 10: "b'0'" 

但這個工程:

In [103]: np.genfromtxt(txt.splitlines()[1:], dtype=dt) 
Out[103]: 
array([(0,), (1,)], 
     dtype=[('n', '<i4')]) 

還是讓genfromtxt創建D型:

In [105]: np.genfromtxt(txt.splitlines(), dtype=None, names=True) 
Out[105]: 
array([(0,), (1,)], 
     dtype=[('n', '<i4')]) 

所以關於loadtxt如何處理dtype有一些問題。我以前沒見過這個。但是我沒有看到很多加載一列的例子。

+0

解決方案的第一部分(將'r'改爲'rb')不適用於我。事實上,它似乎沒有改變任何東西。我希望能夠使用更類似於第二個建議的內容,但我的實際數據不一定在文件的開頭或結尾。 – Warrick

+0

你的增加間接讓我發現爲什麼我在列表中使用'genfromtxt'得到錯誤,所以我現在基本上正在使用該解決方案。謝謝! – Warrick

+0

感謝您的解決方案。我認爲「開放」在「與」之後缺少, – FiReTiTi