2016-06-28 515 views
1

它必須是那些日子之一。我一直可以使用函數tofile來保存數據。但由於某些原因,今天它不工作:)「OSError:無法以二進制模式將對象數組寫入文件」

import numpy as np 

blah..... 

print(type(blist)) 
npdata = np.array(blist) 
print(type(npdata)) 
npdata.tofile('myfile.dat') 

獲取我的結果如下:

Traceback (most recent call last): 
File "C:/context.py", line 67, in <module> 
npdata.tofile('myfile.dat') 
OSError: cannot write object arrays to a file in binary mode 
<class 'list'> 
<class 'numpy.ndarray'> 

所以說我必須以二進制方式打開文件。但據我所知,我不是以二進制模式打開它。

編輯(問題解決後):當我發佈這個問題時,我假定blist是一個整數列表。相反,它是一列整數列表。問題是,當我創建它時,我得到了一個dtype = object,而不是我期待的dtype = int32。

士氣:確保正確使用np.append/np.extend並始終明確設置dtype。

+1

顯示一些重現問題的示例數據。你期待一個'object' dtype嗎? –

回答

2

根據tofile文檔,如果sep是默認值,它將以二進制模式寫入數組。

In [714]: x 
Out[714]: array([[1, 2, 3], [1, 2]], dtype=object) 

In [715]: x.tofile('test') 
--------------------------------------------------------------------------- 
OSError         Traceback (most recent call last) 
<ipython-input-715-0ff8f3c688ad> in <module>() 
----> 1 x.tofile('test') 

OSError: cannot write object arrays to a file in binary mode 

它打開以二進制模式文件,但隨後發現,該陣列是一個對象陣列,它不能寫入的方式。默認的二進制模式用於快速向文件寫入數字,而不是通用對象。

指定sep,使得它在文本模式下,在這種情況下工作的寫:包含一個發生器

In [716]: x.tofile('test',sep=',') 

In [717]: cat test 
[1, 2, 3],[1, 2] 

我有另一個對象陣列(從另一個問題)。

In [719]: g.tofile('test',sep=',') 

In [720]: cat test 
<generator object <genexpr> at 0xb266632c> 

所以在text模式,tofile寫入陣列到文件的str(x)表示。

np.save更適合處理對象數組。它使用pickle對無法寫入常規數組的對象進行編碼。 np.load可以重新加載這樣的文件。

+0

謝謝。你幫我發現了這個問題。我只是假設我有一個不同的dtype。問題是blist實際上並不是整數列表,而是列表列表,np.array創建的是對象列表,而不是「int32」列表。 –

+0

所以當我在代碼中創建我的blist之前。我正在使用blist.append(),我應該一直使用blist.extend()。 –

+0

與我的'x'一樣,如果子列表的長度不同,則該數組是對象dtype。如果它們大小匹配,則'np.array'傾向於使其成爲2d(或更高)。 – hpaulj

0

打開文件以二進制方式寫入:

with open(filename, 'wb'): 
    do stuff 

讓我知道這對你的作品!