タプルのキーを持つ辞書のように動作するクラスを作成しようとしていますが、このディクショナリを使用してPandasのデータフレームを作成するため、Pandasはタプルをキーとして使用するとマルチインデックス(この場合は正しくない)を意味するため、「真に」タプルとなります。カスタムタプルをキーとした辞書で、パンダのバグを迂回することはできません。
>>> a = {(1,): 1 }
>>> pd.Series(a)
1 NaN
dtype: float64
は何が起こることはパンダが辞書のキーはタプルであることを認識していることであるので、それは想定しています、単一要素のタプルの場合
が、これは例えばとして、バグを生成しますマルチインデックス。次に、タプルのlen
が1であることが分かるので、結局のところプレーンなインデックスを作成することにします。しかし、辞書にはキー
1
がなく、代わりに
(1,)
というキーがあるため、値を格納できない場合は、
NaN
となります。このバグを離れて残し
、いくつかの要素を持つ「普通の」タプルを使用して、パンダが正常に動作しますが、私はしたくないマルチレベルの指標を前提としています私が代わりに欲しい
>>> a = {(1,2): 1 }
>>>> pd.Series(a)
1 2 1
dtype: int64
が使用することですインデックスとしてタプル(1,2)
。
collections
標準ライブラリの
UserList
の実装を模倣しますが、最低限にそれを維持)のように、私自身の
Tuple
クラスを実装することを決定した
:私はキーとして、オブジェクトのこの種を使用する場合は
from collections.abc import Sequence
class Tuple(Sequence):
def __init__(self, initlist=None):
self.data =()
if initlist is not None:
if type(initlist) == type(self.data):
self.data = initlist
elif isinstance(initlist, Tuple):
self.data = initlist.data
else:
self.data = tuple(initlist)
def __getitem__(self, i): return self.data[i]
def __len__(self): return len(self.data)
def __hash__(self): return hash(self.data)
def __repr__(self): return repr(self.data)
Sequence.register(Tuple)
キーはタプルであるかのよう
>>> a = {Tuple((1,2)): 1}
>>> pd.Series(a)
(1, 2) 1
dtype: int64
辞書が見えます:
私の辞書に、パンダはマルチインデックスを生成するためにそれを停止し、インデックスなどのオブジェクトを、使用することを余儀なくされます>>> a
{(1, 2): 1}
これまでのところ、とても良いです。しかし、奇妙なことが起こる:
>>> a[Tuple((1,2))]
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-169-9641d6999f03> in <module>()
----> 1 a[Tuple((1,2))]
KeyError: (1, 2)
なぜですか?私の知る限り、Python辞書は、Tuple.__hash__()
が内部でハッシュすることによって、Tuple.__hash__()
が実行する、指定されたキーのハッシュを計算することによって値を見つける必要があります。data
次に、キーが見つからない理由は何ですか?
私はTupleクラスに他のいくつかのメソッドを実装する必要があると思いますが、どのクラスまたはその理由がわかりません。
[ハッシュ可能](https://docs.python.org/2/glossary.html#term-hashable)に必要な比較方法のいずれかを実装しようとしましたか? – languitar
@languitarはい!'__eq __()'は欠けていたメソッドでした。私は馬鹿だと感じる。ありがとうございました!あなたのコメントから答えを出したら、私はそれを受け入れます。 – JLDiaz