1. ホーム
  2. プログラミング言語
  3. パイソン

Pandas reports TypeError: 'Series' object are mutable, thus they cannot be hashed.

2022-01-21 10:14:30

I. 必要条件

元のCSVファイルのA列の値を元に、B列を追加する。

II. トライ1

1. A列をキー、B列を値とする辞書dictに、A列とB列に対応する値を書き込め。

2. CSVファイルを次のように処理します。 データフレーム .

3. 

  1. import pandas as pd
  2. # If df['A'] exists in dict_a, then take value, value, otherwise use default value 15
  3. dict_a = {'a':1,'b':1,'c':2,'d':4,'d':3}
  4. df = pd.read_csv(example.csv)
  5. df['B'] = dict_a[df['A']]
  6. # The previous sentence reports an error: TypeError: 'Series' objects are mutable, thus they cannot be hashed

を使用する場合 パンダ ファイルを処理する際に、エラーが報告されます。TypeError: 'Series' objects are mutable, thus they cannot be hashed, means that df['B'] as whole is a Series, which is mutable, and thus cannot be retrieve and assign as an index.これは、df['B']が全体としてSeriesであり、mutableであり、インデックスとして取得することができないことを意味します。

III. トライ2

forループを使って、DataFrameの各行を以下のコードで反復処理します。

  1. data = pd.read_csv('example.csv')
  2. df = pd.DataFrame(data)
  3. df['B'] = 15 # Set the default value to 15
  4. # iterrows traverses each row of the DataFrame
  5. for index, row in df.iterrows():
  6. if row['A'] in dict_a:
  7. print(row['B'])
  8. row['B'] = dict_a[row['A']]
  9. print(row['B'])
  10. else:
  11. row['B'] = 15
  12. df.to_csv('finished.csv')

印刷結果は、割り当てがうまくいったことを示しますが、結果のファイルは変更されていません。

その理由は、iterrowsは行を修正してはならず、反復処理されているものを修正してはならないからです。これは、すべてのケースで動作することを保証するものではありません。データ型によっては、イテレータはビューではなくコピーを返しますので、それに対する書き込みはうまくいきません。

IV. ソリューション

最後に、ラムダ関数と  df.apply() function を使用して、行をたどり、複数の列にアクセスする関数です。

コードはこのようになります。

  1. # Note that the formula() function must have a return value, otherwise the following apply function will not work
  2. def formula(x):
  3. if x in slidetime_dict:
  4. return slidetime_dict[x]
  5. else:
  6. return 15
  7. df['slidetime'] = df.apply(lambda row: formula(row['A']), axis=1)

上記、問題解決。

---------- ---------- ---------- ---------- ---------- --

追加知識の更新。

pandas が apply() 関数を使うとき、呼び出された関数 (この場合は formula()) の様々な条件分岐は戻り値を持たなければならず、そうでなければ生成された結果は不正確です。