web-dev-qa-db-ja.com

NumPy: 'np.save()'を 'allow_pickle = False'と共に使用した結果

NumPyドキュメント here によると、デフォルトでは、マトリックスはallow_pickle=Trueで保存され、さらに、このデフォルトの動作で何が問題になる可能性があるかがわかります。

allow_pickle:bool、オプション
Pythonピクルを使用してオブジェクト配列を保存できるようにします。ピクルを禁止する理由には、セキュリティ(ピクルされたデータをロードすると任意のコードを実行できる)と移植性(ピクル化されたオブジェクトが異なるPythonインストールでロードできない可能性がある、たとえば、格納されたオブジェクトが利用できないライブラリを必要とする場合など)すべての漬物データはPython 2とPython 3の間で互換性があります。
デフォルト:True

それを読んだ後は、もちろんallow_pickle=Falseを使用したいと思いますが、この方法で使用した場合の違いはわかりません。デメリットにもかかわらず、デフォルトでallow_pickel=Trueを使用する理由はいくつかあるに違いありません。

allow_pickle=Falseを使用しているかどうか、および動作がどのように異なるかを教えてください。

11
SalatYerakot

オブジェクト配列は、dtypeobjectである通常の単純な配列です。これは、配列の内容が通常の数値型(intまたはfloatなど)でない場合に発生します。これがどのように機能するかをテストするために、オブジェクトを含む数の多い配列を保存してみることができます。単純な種類のオブジェクトはdictです。

>>> import numpy as np
>>> a = np.array([{x: 1} for x in range(4)])
>>> a
array([{0: 1}, {1: 1}, {2: 1}, {3: 1}], dtype=object)
>>> np.save('test.pkl', a)

これをロードすると正常に動作します:

>>> np.load('test.pkl.npy')
array([{0: 1}, {1: 1}, {2: 1}, {3: 1}], dtype=object)

ただし、ピクルを使用しないと配列を保存できません。

>>> np.save('test.pkl', a, allow_pickle=False)
...
ValueError: Object arrays cannot be saved when allow_pickle=False

ピクルスの経験則では、作成したピクルスをロードする場合は安全ですが、他の場所から入手したピクルスをロードする場合は注意が必要です。 1つには、ピクルを作成するために使用されたのと同じライブラリ(またはライブラリバージョン)がインストールされていない場合、ピクルをロードできない可能性があります(これは移植性が意味するものです) 上記)。 セキュリティはもう1つの潜在的な懸念事項です。ピクルスがどのように乱用されるかについては、たとえば この記事 で少し読むことができます。

8
wildwilhelm