2017-07-16 16 views
0

numpyを含むプログラムを書く中で、メンバーシップテストがnumpy dtypeオブジェクトに対して期待通りに機能しないことがわかりました。具体的には、結果はsetでは予期しないが、listまたはtupleでは発生しません。メンバーシップテストのnumpy dtypeが奇妙な結果をもたらす

import numpy as np 
x = np.arange(5).dtype 
y = np.int64 
print(x in {y}, x in (y,), x in [y]) 

結果はFalse True Trueです。

は、Python 2.7と3.6の両方でnumpy 1.12.xがインストールされていることがわかりました。

理由は何ですか?

UPDATE

はDTYPEオブジェクトはPythonでハッシュ化に関するいくつかの仮定を尊重しないということになります。

http://www.asmeurer.com/blog/posts/what-happens-when-you-mess-with-hashing-in-python/

https://github.com/numpy/numpy/issues/5345

DTYPEオブジェクトの__hash____eq__実装はかなり悪い考え抜かれたser2357112と@Fabien

答えて

1

@感謝。とりわけ、__hash____eq__の実装では、一貫性がありません。あなたはここの効果を見ています。

__hash____eq__ DTYPEと他のいくつかの問題が

  • DTYPEオブジェクトはハッシュ可能オブジェクトの真のであってはなりません両方__hash____eq__、何かに影響を与える方法で、実際に変更可能であることをしています。 (具体的には構造化dtypeのnamesを再割り当てすることができます)
  • dtypeの等価性は推移的ではありません。たとえば、xyの質問では、x == yx == 'int64'ですが、y != 'int64'です。
  • dtype __eq__は、NotImplementedを返すときにTypeErrorを発生させます。

バグレポートを提出することはできますが、それらの方法に関連するを見ると、修正される可能性は低いです。デザインはあまりにも混乱しており、人々はすでに壊れた部分に頼っています。

+0

ありがとうございます!本当にそれを見てまで、どのように乱雑なnumpyの内部があるかわからない... – zym1010

0

setsは、inキーワードをPythonでどのように実装するのかが異なります。

リストは、単に各オブジェクトを調べて、同等かどうかをチェックします。オブジェクトの最初のハッシュを設定します。

different meaning of the 'in' keyword for sets and lists

セットは一意性を確保する必要があるためです。しかし、あなたのオブジェクトは等価ではありません:

ハッシングはおそらく異なる結果をもたらします。

+0

ありがとう。私は他のいくつかのソースを見て、http://www.asmeurer.com/blog/posts/what-happens-when-you-mess-with-hashing-in-python/のように、numpyがdtype用のハッシュ関数を実装しているようですオブジェクトが不十分ですか? – zym1010

+0

[hpaulj](https://stackoverflow.com/questions/35293672/why-do-these-dtypes-compare-equal-but-hash-different)によると、「np.dtypeは特別なハッシュを定義していないようですメソッドでは、オブジェクトから継承します。 "、そうです...リスト内では(__)'あなたに仕事をさせます、 '__equal __()'はうまくいくようです – Fabien