概要
- pandas.DataFrameで複数の行や列をまとめて削除する方法
- 削除したい行名・列名のリストを渡してdrop()で削除する
動作環境
pandas 1.x以降であれば、この記事のコードはそのまま動きます。後半で触れる index= / columns= を使う書き方はpandas 0.21以降で使えます。
解決方法
準備
"""DataFrameを準備"""
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(4, 4))
df.index = ['idx1', 'idx2', 'idx3', 'idx4']
df.columns = ['col1', 'col2', 'col3', 'col4']
"""出力結果"""
df
col1 col2 col3 col4
idx1 0.660757 0.122939 0.450455 0.000483
idx2 1.948787 2.327604 0.626010 -0.092082
idx3 0.311708 0.926246 -0.083588 0.487964
idx4 0.284561 -0.076556 1.183666 -0.142197
削除したい行・列を指定する
drop_idx = ['idx2', 'idx3']
drop_col = ['col1', 'col4']
行を削除する
df.drop(drop_idx, axis=0)
"""出力結果"""
col1 col2 col3 col4
idx1 0.660757 0.122939 0.450455 0.000483
idx4 0.284561 -0.076556 1.183666 -0.142197
列を削除する
df.drop(drop_col, axis=1)
"""出力結果"""
col2 col3
idx1 0.122939 0.450455
idx2 2.327604 0.626010
idx3 0.926246 -0.083588
idx4 -0.076556 1.183666
つまずきやすい点
元のDataFrameは変更されない
drop() は削除後のコピーを返すメソッドで、元のDataFrameはそのまま残ります。ここを勘違いすると「削除したはずなのに消えていない」ということになります。
df.drop(drop_idx, axis=0) # 戻り値を捨てているので、dfは変わらない
df = df.drop(drop_idx, axis=0) # 代入して受け取る
inplace=True を指定すれば元のDataFrameを直接変更できますが、戻り値が None になるのでメソッドチェーンはできません。個人的には、代入して受け取る書き方に統一しておく方が事故が少ないと思います。
axisの数字を覚えなくていい書き方
axis=0 が行で axis=1 が列というのは、慣れるまで毎回迷います。次のようにキーワードで指定すると、そもそも覚える必要がなくなります。
df.drop(index=drop_idx) # 行を削除
df.drop(columns=drop_col) # 列を削除
df.drop(index=drop_idx, columns=drop_col) # 両方まとめて
行と列を同時に指定できるのも、この書き方の利点です。
存在しないラベルを指定するとエラーになる
指定した名前がDataFrameに無い場合、KeyError になります。
df.drop(columns=['col5'])
# KeyError: "['col5'] not found in axis"
あってもなくても消したい、という場合は errors='ignore' を付けます。列の構成が実行ごとに変わりうるデータを処理するときによく使います。
df.drop(columns=['col5'], errors='ignore') # 無ければ何もしない
同じ pandas.DataFrame の操作では、値の置換についてpandas.DataFrameで置換処理に、Excelファイルの読み込みについてpandasを使ってExcelを読み込むにまとめています。条件で行を絞り込もうとして真偽値まわりのエラーが出た場合はValueError: The truth value of a Series is ambiguous.を参照してください。