2014-03-26 66 views
8

我可以使用np.savez存儲字典嗎? 結果令人驚訝(至少對我來說),而且我找不到一種方法可以通過密鑰將數據還給我。用np.savez存儲一個字典給出了意想不到的結果?

In [1]: a = {'0': {'A': array([1,2,3]), 'B': array([4,5,6])}} 
In [2]: a 
Out[2]: {'0': {'A': array([1, 2, 3]), 'B': array([4, 5, 6])}} 

In [3]: np.savez('model.npz', **a) 
In [4]: a = np.load('model.npz') 
In [5]: a 
Out[5]: <numpy.lib.npyio.NpzFile at 0x7fc9f8acaad0> 

In [6]: a['0'] 
Out[6]: array({'B': array([4, 5, 6]), 'A': array([1, 2, 3])}, dtype=object) 

In [7]: a['0']['B'] 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-16-c916b98771c9> in <module>() 
----> 1 a['0']['B'] 

ValueError: field named B not found 

In [8]: dict(a['0']) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-17-d06b11e8a048> in <module>() 
----> 1 dict(a['0']) 

TypeError: iteration over a 0-d array 

我不明白到底發生了什麼事情。看起來我的數據變成了一個0維數組中的字典,讓我無法通過密鑰獲取我的數據。或者我錯過了什麼?

所以我的問題是:

  1. 這裏會發生什麼?如果我仍然可以通過密鑰訪問我的數據,如何?
  2. 什麼是最好的方式來存儲這種類型的數據? (以str作爲鍵和其他詞典作爲值的字典)

謝謝!

回答

9

,能夠恢復數據:

In [41]: a = {'0': {'A': array([1,2,3]), 'B': array([4,5,6])}} 

In [42]: np.savez('/tmp/model.npz', **a) 

In [43]: a = np.load('/tmp/model.npz') 

注意,D型細胞是「對象」。

In [44]: a['0'] 
Out[44]: array({'A': array([1, 2, 3]), 'B': array([4, 5, 6])}, dtype=object) 

並且數組中只有一個項目。該項目是一個Python字典!

In [45]: a['0'].size 
Out[45]: 1 

您可以檢索使用item()方法的值(注:這是items()法字典,也沒有什麼內在的NpzFile 類,但就是numpy.ndarray.item() method 那份在價值。該陣列爲標準Python scalarsobject D型細胞在陣列(即使詞典)的小區持有的任何值的陣列是一個Python標量:

In [46]: a['0'].item() 
Out[46]: {'A': array([1, 2, 3]), 'B': array([4, 5, 6])} 

In [47]: a['0'].item()['A'] 
Out[47]: array([1, 2, 3]) 

In [48]: a['0'].item()['B'] 
Out[48]: array([4, 5, 6]) 

要恢復a作爲類型的字典字典:

In [84]: a = np.load('/tmp/model.npz') 

In [85]: a = {key:a[key].item() for key in a} 

In [86]: a['0']['A'] 
Out[86]: array([1, 2, 3]) 
+0

感謝unutbu,這很清楚。雖然在腳本中以這種方式實際存儲和恢復數據似乎過於複雜,但我仍然有興趣瞭解您/他人如何存儲此類數據。泡菜也許? – louic

+0

我認爲首先要考慮的是如果你真的需要一個字典的字典。這真的是最好的數據結構嗎?一個缺點是它打破了你的numpy陣列。無論何時您想對每個數組執行操作,小型或許多NumPy數組都需要Python循環。當你可以在一個大的numpy數組上執行NumPy操作時,你可以從NumPy中獲得更好的性能,因爲這會將更多工作推入快速的底層C/Fortran函數中,而減少到相對較慢的Python循環。 – unutbu

+0

您可能需要調查[Pandas](http://pandas.pydata.org)DataFrames。您可以使用帶有多索引的DataFrame來替換字典密鑰的兩個級別。您可以將DataFrame存儲爲高性能壓縮格式,如hdf5。 – unutbu

1

基於這樣的回答:recover dict from 0-d numpy array

a = {'key': 'val'} 
scipy.savez('file.npz', a=a) # note the use of a keyword for ease later 

可以使用

get = scipy.load('file.npz') 
a = get['a'][()] # this is crazy maybe, but true 
print a['key'] 

它也可以不使用關鍵字參數,但我認爲這也值得分享。

相關問題