Python Pandas:Drop DuplicatesFunction-異常な動作

0
2022.01.15

エラー -> TypeError: ハッシュできない型: 'list' は、データ フレームを保存して再度読み込んだ後に 表示されなくなります

[保存され、ロードされ、生成された]両方のデータフレームは、 同じdtypes を持っています.

再現性 ->

--> import pandas as pd
--> l1 = [[1], [1], [1], [1], [1], [1], [1], [1], [6], [1], [6], [1], [6], [6], [6], [6], [6], [6], [6], [6], [6]]

## len(l1) is 21 ##

--> l2 = ['a']*21
--> l3 = ['c']*10 + ['d']*10 + ['e']
--> df = pd.DataFrame()
--> df['col1'], df['col2'], df['col3'] = l1, l3, l2
--> df
        col1 col2 col3
        0   [1]    c    a
        1   [1]    c    a
        2   [1]    c    a
        3   [1]    c    a
        4   [1]    c    a
        5   [1]    c    a
        6   [1]    c    a
        7   [1]    c    a
        8   [6]    c    a
        9   [1]    c    a
        10  [6]    d    a
        11  [1]    d    a
        12  [6]    d    a
        13  [6]    d    a
        14  [6]    d    a
        15  [6]    d    a
        16  [6]    d    a
        17  [6]    d    a
        18  [6]    d    a
        19  [6]    d    a
        20  [6]    e    a

--> df.dtypes
        col1    object
        col2    object
        col3    object
        dtype: object

--> df.drop_duplicates(subset=['col1', 'col2', 'col3'], keep='last', inplace=True)
        
        ## TypeError: unhashable type: 'list' ##

## Here if I save it as an excel and load again, then this error does not come up ... ##

--> df.to_excel('test.xlsx')
--> df_ = pd.read_excel('test.xlsx')
--> df_.dtypes
        Unnamed: 0     int64
        col1    object
        col2    object
        col3    object
        dtype: object
--> df_.drop_duplicates(subset=['col1', 'col2', 'col3'], keep='last', inplace=True)
--> df_
         Unnamed: 0 col1 col2 col3
        8       8   [6]    c    a
        9       9   [1]    c    a
        11      11  [1]    d    a
        19      19  [6]    d    a
        20      20  [6]    e    a

この振る舞いには 説明がありますか?

問題の拡張トレースバック

トレースバック (最後の最後の呼び出し):

ファイル ""、1 行目、in

ファイル "C:\ユーザー\Agnij\Anaconda3\lib\サイトパッケージ\pandas\コア\frame.py",4811行目 drop_duplicates

重複 = self.duplicated(サブセット、キープ=キープ)

ファイル "C:\Users\Agnij\Anaconda3\lib\サイトパッケージ\pandas\コア\frame.py"、4888行目、複製されたラベルで、形状 = マップ(リスト、zip(*map(f、ヴァルス))

ファイル "C:\ユーザー\Agnij\Anaconda3\lib\サイトパッケージ\pandas\コア\frame.py", 行 4863, f vals, size_hint=分 (len(self), _SIZE_HINT_LIMIT)

ファイル "C:\Users\Agnij\Anaconda3\lib\サイトパッケージ\pandas\コア\algorithms.py", 行 636, 値を分解, na_sentinel=na_sentinel, size_hint=size_hint, na_value=na_value

ファイル "C:\ユーザー\Agnij\Anaconda3\lib\サイトパッケージ\pandas\コア\algorithms.py",484行目,_factorize_array一意,コード=table.factorize(値,na_sentinel=na_sentinel,na_value=na_value)

ファイル "pandas_libs\hashtable_class_helper.pxi"、行 1815、pandas._libs.ハッシュテーブル.PyObjectHashTable.ファクタリゼーズ

ファイル "pandas_libs\hashtable_class_helper.pxi"、行 1731、pandas._libs.ハッシュテーブル.PyObjectHashTable._ユニーク

回答
2
2022.01.15

drop_duplicates はオブジェクトをハッシュして、どのオブジェクトが見られたか見ていないかを効率的に追跡します。

listはハッシュ可能ではない (変更可能なため) ため、drop_duplicatesを直接使用することはできません。データを保存して読み込むときに、ハッシュを計算できる文字列に変換される可能性があります。

この問題を解決するには、リストをハッシュ可能なタプルに変換します。

df['col1'] = df['col1'].apply(tuple)
# now this runs with no error
df.drop_duplicates(subset=['col1', 'col2', 'col3'], keep='last', inplace=True)