[pandas]ValueError: Grouper for ‘[column_name]’ not 1-dimensionalと出る

はじめに

pandas.groupby()を実行すると以下のエラーメッセージが出ました。

ValueError: Grouper for '[column_name]' not 1-dimensional

エラーメッセージを読んでデータの中身を見ると、操作の途中で誤って同名のカラムが複数できてしまっていることが原因のようです。

    a   b   c   a
0   1   2   3   1
1   2   4   2   2
2   3   6   2   3
3   4   7   3   4
...

なので列を削除します。

df = df.loc[:,~df.columns.duplicated()]
df

    a   b   c
0   1   2   3
1   2   4   2
2   3   6   2
3   4   7   3

削除できました。

df.groupby(['a'], as_index=False).count()['c']

0    1
1    1
2    1
3    1
Name: c, dtype: int64

エラーも出ません。よっしゃ。

細かく見ていく

df = df.loc[:,~df.columns.duplicated()]

dfから重複している列を除いてdfに代入する、という処理です。

df.loc

ラベルで指定した一つ以上の要素の取得・変更ができます。

df.loc[{行範囲の指定}, {列範囲の指定}]

具体的には、以下のように書き、
[]のカンマ区切りの1つ目で行範囲の指定(:で全部)、
2つ目で取得する列ラベル(‘b’の列)を指定しています。

df.loc[:, 'b']

0    2
1    4
2    6
Name: b, dtype: int64

df.columns.duplicated()

データフレームの列ラベルのリストを取得し、それが重複しているかをTrue/Falseで配列に格納しています。

df.columns.duplicated()

array([False, False, False,  True])

~(否定)

locの列範囲指定において、df.columns.duplicated()によって取得した重複している列ラベル以外のラベルを指定します。
結果として、重複を除外したデータが得られます。

~を外すと当然、重複している列ラベルのデータが取得できます。

df_2.loc[:, df_2.columns.duplicated()]

    a
0   1
1   2
2   3
3   4

値が同じなので分かりづらいですが、ここで取得されるのは2つ目のa列です。

まとめ

行の重複の取り扱いでもduplicated()はよく使うみたいです。
重複させてしまったら、落ち着いて処理しましょう。

参考