2013-10-28 34 views
1

我有大量的numpy ndarrays存儲在字符串中。這可能是一個糟糕的設計選擇,但這是我所做的,現在挑選的字符串似乎已被轉換或一路上,當我試圖unpickle我注意到他們是str類型,我得到以下錯誤:從python/numpy轉換後的字符串中取消打印

TypeError: 'str' does not support the buffer interface 

當調用

numpy.loads(bin_str) 

哪裏bin_str是我試圖unpickle的東西。如果我打印出bin_str它看起來像

b'\x80\x02cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\x01K\x00\x85q\x02c_codecs\nencode\nq\x03X\x01\x00\x00\ ... 

持續一段時間,所以信息似乎是在那裏,我只是不太確定如何將它轉換成任何字符串格式numpy的/泡菜的需求。心血來潮我試圖

numpy.loads(bytearray(bin_str, encoding='utf-8')) 

numpy.loads(bin_str.encode()) 

這兩個拋出一個錯誤_pickle.UnpicklingError: unpickling stack underflow。有任何想法嗎?

PS:我對Python的3.3.2和1.7.1 numpy的

編輯

我發現,如果我做到以下幾點:

open('temp.txt', 'wb').write(...) 
return numpy.load('temp.txt') 

我找回我陣列,並且...表示從另一個窗口複製並粘貼輸出print(bin_str)。我試圖直接寫文件bin_str直接去unpickle,但不起作用,它抱怨TypeError: 'str' does not support the buffer interface。將bin_str轉換爲可以將直接寫入二進制文件的一些理智方法會在嘗試讀取時導致醃製錯誤。

編輯2 所以我猜發生了什麼事是我的二進制泡菜字符串結束了編碼的普通字符串裏面,是這樣的:

"b'pickle'" 

這是不幸的,我還沒有想出如何對付,除了這個荒謬和令人費解的方式把它找回來:

open('temp.py', 'w').write('foo = ' + bin_str) 
from temp import foo 
numpy.loads(foo) 

這似乎是一個很丟人的解決問題的辦法,所以請給我一個更好的!

回答

2

這聽起來像你保存的字符串是repr S按你的酸洗代碼返回原bytes實例。這有點不幸,但不是太糟糕。repr打算返回一個對象的「機友」表示,它往往可以逆轉使用eval

import numpy as np 
import pickle 

# this part has already happened 
orig_obj = np.array([1,2,3]) 
orig_pickle = pickle.dumps(orig_obj) 
saved_str = repr(orig_pickle)  # this was a mistake, but it's already done 

# this is what you need to do to get something equivalent to orig_obj back 
reconstructed_pickle = eval(saved_str) 
reconstructed_obj = pickle.loads(reconstructed_pickle) 

# test 
if np.all(reconstructed_obj == orig_obj): 
    print("It worked!") 

強制性注意使用eval可能是危險的:要知道,eval可以運行任何Python代碼它想要的,所以不要用不可信的數據來調用它。然而,pickle數據具有相同的風險(惡意pickle字符串可以在取消打開時運行任意代碼),所以在這種情況下你不會失去很多安全性。無論如何,我猜你相信你的數據在這種情況下。

+0

謝謝!這是完美的。我不知道eval/exec是否在語言中,嘿。 –

相關問題