1

我有大量存储为字符串的 numpy ndarrays。这可能是一个糟糕的设计选择,但它就是我所做的,现在挑选的字符串似乎已经被转换或其他东西,当我尝试取消腌制时,我注意到它们是类型str并且我收到以下错误:

TypeError: 'str' does not support the buffer interface

当我调用

numpy.loads(bin_str)

bin_str我要解开的东西在哪里。如果我打印出来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/pickle 需要的任何字符串格式。一时兴起我尝试了

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

numpy.loads( bin_str.encode() )

两者都抛出错误_pickle.UnpicklingError: unpickling stack underflow。有任何想法吗?

PS:我在 python 3.3.2 和 numpy 1.7.1

编辑

我发现如果我执行以下操作:

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

我取回我的数组,并...表示从另一个窗口复制和粘贴输出。print(bin_str)我尝试bin_str直接写入文件以取消腌制,但这不起作用,它抱怨TypeError: 'str' does not support the buffer interface. 转换bin_str可以直接写入二进制文件的内容的一些明智的方法会在尝试读回它时导致 pickle 错误。

编辑 2 所以我猜发生的事情是我的二进制泡菜字符串最终编码在一个普通字符串中,例如:

"b'pickle'"

这是不幸的,我还没有想出如何处理它,除了这种荒谬和复杂的方式来取回它:

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

这似乎是一个非常可耻的问题解决方案,所以请给我一个更好的解决方案!

4

1 回答 1

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 字符串可以在 unpickle 时运行任意代码),因此在这种情况下您不会失去太多安全性。无论如何,我猜你在这种情况下相信你的数据。

于 2013-10-28T22:33:05.237 回答