pandasのDataFrameから「この行だけ消したい」「この列は分析に使わないので削除したい」というときは、drop()を使います。
ただし、初めて使うと「axis=0とaxis=1のどちら?」「削除したのに元のDataFrameが変わらない」「上から2行目を消したつもりが別の行が消えた」と迷いやすいメソッドでもあります。
この記事では、Google Colabでそのまま実行できるコードを使い、行・列の削除から複数指定、条件削除、エラー対策まで順番に確認します。
この記事でわかること
drop(index=...)で指定した行を削除する方法drop(columns=...)で指定した列を削除する方法- 行ラベルと「上から何行目」という位置の違い
- 複数行・複数列や、行と列を同時に削除する方法
drop()が反映されない原因とinplace=Trueの注意点KeyErrorが出たときの確認方法drop()・dropna()・drop_duplicates()の使い分け
DataFrameそのものから確認したい方は、先にDataFrameの作り方と基本操作をご覧ください。
先に結論:行はindex、列はcolumnsで削除する
初心者は、次の2つを基本形として覚えると迷いにくくなります。
| 削除したいもの | 推奨コード | 指定するもの |
|---|---|---|
| 1行 | df.drop(index=行ラベル) |
DataFrameのindex |
| 1列 | df.drop(columns="列名") |
DataFrameの列名 |
| 複数行 | df.drop(index=[行ラベル1, 行ラベル2]) |
行ラベルのリスト |
| 複数列 | df.drop(columns=["列名1", "列名2"]) |
列名のリスト |
axis=0とaxis=1でも指定できますが、index=・columns=のほうが、行と列のどちらを削除するのかコードから読み取りやすくなります。
pandas drop()とは
DataFrame.drop()は、指定した行ラベルまたは列ラベルを除いたDataFrameを返すメソッドです。
通常は元のDataFrameを直接変更しません。結果を残す場合は、df = df.drop(...)のように変数へ代入します。この点が「実行したのに削除が反映されない」と感じる主な原因です。
サンプルデータを用意する
最初にpandasのバージョンを確認し、5件の売上データを作ります。この記事では、すべてこのDataFrameを使います。
import pandas as pd
print("pandas version:", pd.__version__)
df = pd.DataFrame(
{
"商品": ["ノートPC", "マウス", "キーボード", "モニター", "USBメモリ"],
"地域": ["東京", "大阪", "東京", "名古屋", "大阪"],
"売上": [1200, 800, 1500, 700, 1100],
"利益": [240, 160, 300, 140, 220],
},
index=[100, 101, 102, 103, 104],
)
print(df)
pandas version: 2.2.3
商品 地域 売上 利益
100 ノートPC 東京 1200 240
101 マウス 大阪 800 160
102 キーボード 東京 1500 300
103 モニター 名古屋 700 140
104 USBメモリ 大阪 1100 220
左端の100〜104が行のindexラベルです。表の上から数えた位置とは別の情報として扱います。
drop()で行を削除する
indexラベルを指定して1行削除する
indexラベル101の行を削除します。目的は「マウスの行を削除する」ことです。
df_row_dropped = df.drop(index=101)
print(df_row_dropped)
商品 地域 売上 利益
100 ノートPC 東京 1200 240
102 キーボード 東京 1500 300
103 モニター 名古屋 700 140
104 USBメモリ 大阪 1100 220
indexラベル101の行だけがなくなりました。元のdfではなく、結果をdf_row_droppedへ代入しています。
複数行をリストでまとめて削除する
複数の行は、indexラベルをリストで渡します。
df_rows_dropped = df.drop(index=[101, 103])
print(df_rows_dropped)
商品 地域 売上 利益
100 ノートPC 東京 1200 240
102 キーボード 東京 1500 300
104 USBメモリ 大阪 1100 220
indexラベル101と103の2行が削除されました。
行ラベルと行番号の違い
drop(index=101)の101は「上から101行目」ではなく、indexラベル101です。
上から2行目を削除したい場合は、df.index[1]でその位置にあるラベルを取得します。Pythonは0から数えるため、[1]が上から2行目です。
second_row_label = df.index[1]
print("上から2行目のindexラベル:", second_row_label)
df_by_position = df.drop(index=second_row_label)
print(df_by_position)
上から2行目のindexラベル: 101
商品 地域 売上 利益
100 ノートPC 東京 1200 240
102 キーボード 東京 1500 300
103 モニター 名古屋 700 140
104 USBメモリ 大阪 1100 220
今回は上から2行目のラベルが101なので、マウスの行が削除されました。indexが並べ替えられていたり、文字列になっていたりしても、位置からラベルを取得すれば意図を明確にできます。
drop()で列を削除する
columnsで1列削除する
「利益」列を削除します。
df_column_dropped = df.drop(columns="利益")
print(df_column_dropped)
商品 地域 売上
100 ノートPC 東京 1200
101 マウス 大阪 800
102 キーボード 東京 1500
103 モニター 名古屋 700
104 USBメモリ 大阪 1100
「利益」列だけがなくなり、「商品」「地域」「売上」は残っています。
複数列をリストでまとめて削除する
df_columns_dropped = df.drop(columns=["地域", "利益"])
print(df_columns_dropped)
商品 売上
100 ノートPC 1200
101 マウス 800
102 キーボード 1500
103 モニター 700
104 USBメモリ 1100
「地域」と「利益」の2列が削除されました。
列番号で指定するときはdf.columnsを使う
上からではなく左から2列目を削除したい場合は、df.columns[1]で列名を取得します。
second_column_name = df.columns[1]
print("左から2列目の列名:", second_column_name)
df_by_column_position = df.drop(columns=second_column_name)
print(df_by_column_position)
左から2列目の列名: 地域
商品 売上 利益
100 ノートPC 1200 240
101 マウス 800 160
102 キーボード 1500 300
103 モニター 700 140
104 USBメモリ 1100 220
左から2列目は「地域」なので、その列が削除されました。列番号を直接columns=1へ渡すのではなく、df.columns[1]から実際の列名を取得する点が重要です。
行と列を同時に削除する
index=とcolumns=は同時に指定できます。ここでは2行と1列を一度に削除します。
df_both_dropped = df.drop(index=[101, 103], columns=["利益"])
print(df_both_dropped)
商品 地域 売上
100 ノートPC 東京 1200
102 キーボード 東京 1500
104 USBメモリ 大阪 1100
indexラベル101・103の行と、「利益」列が同時に削除されています。
axis=0とaxis=1の違い
labelsとaxisを組み合わせる書き方もあります。
| axis | 対象 | index・columnsで書く場合 |
|---|---|---|
axis=0またはaxis="index" |
行 | index=... |
axis=1またはaxis="columns" |
列 | columns=... |
次の2つは同じ結果になります。
result_with_axis = df.drop(labels="利益", axis=1)
result_with_columns = df.drop(columns="利益")
print("2つの結果は同じ:", result_with_axis.equals(result_with_columns))
print(result_with_axis)
2つの結果は同じ: True
商品 地域 売上
100 ノートPC 東京 1200
101 マウス 大阪 800
102 キーボード 東京 1500
103 モニター 名古屋 700
104 USBメモリ 大阪 1100
Trueと表示されれば、2つの結果は同じです。既存コードを読むためにaxisの意味は必要ですが、自分で書くときはindex=・columns=を使うと取り違えを減らせます。
条件に合う行を削除する
「売上が1000未満の行を削除する」場合は、最初に条件に合う行のindexを取得し、そのindexをdrop()へ渡します。
delete_index = df.index[df["売上"] < 1000]
print("削除対象のindex:", delete_index.tolist())
df_condition_dropped = df.drop(index=delete_index)
print(df_condition_dropped)
削除対象のindex: [101, 103]
商品 地域 売上 利益
100 ノートPC 東京 1200 240
102 キーボード 東京 1500 300
104 USBメモリ 大阪 1100 220
売上が1000未満のindexラベル101と103が削除されました。
同じ結果は「売上が1000以上の行だけ残す」と考えて、条件抽出でも作れます。
df_filtered = df[df["売上"] >= 1000]
print("drop()と条件抽出の結果は同じ:", df_condition_dropped.equals(df_filtered))
print(df_filtered)
drop()と条件抽出の結果は同じ: True
商品 地域 売上 利益
100 ノートPC 東京 1200 240
102 キーボード 東京 1500 300
104 USBメモリ 大阪 1100 220
結果は同じです。削除対象のindexが明確ならdrop()、残す条件をそのまま表現したいなら条件抽出が読みやすいことがあります。条件式を反転させると結果も逆になるため、処理前後の行数を必ず確認しましょう。
条件指定を詳しく確認したい方は、pandasでAND・OR・queryを使って条件抽出する方法も参考にしてください。
処理前後表で確認する
| 操作 | 処理前 | 指定 | 処理後 |
|---|---|---|---|
| 1行削除 | 5行×4列 | index=101 |
4行×4列 |
| 1列削除 | 5行×4列 | columns="利益" |
5行×3列 |
| 2行・1列を同時削除 | 5行×4列 | index=[101, 103], columns=["利益"] |
3行×3列 |
| 条件削除 | 5行×4列 | 売上1000未満 | 3行×4列 |
行数・列数はshapeでも検証できます。
print("処理前:", df.shape)
print("1行削除後:", df_row_dropped.shape)
print("1列削除後:", df_column_dropped.shape)
print("行・列の同時削除後:", df_both_dropped.shape)
print("条件削除後:", df_condition_dropped.shape)
処理前: (5, 4)
1行削除後: (4, 4)
1列削除後: (5, 3)
行・列の同時削除後: (3, 3)
条件削除後: (3, 4)
drop()が反映されない原因
戻り値を変数へ代入する
通常のdrop()は、削除後の新しいDataFrameを返します。元のdfは変わりません。
temporary_result = df.drop(index=101)
print("削除結果の行数:", len(temporary_result))
print("元のdfの行数:", len(df))
削除結果の行数: 4
元のdfの行数: 5
削除結果は4行ですが、元のdfは5行のままです。結果を反映するなら、次のように再代入します。
df = df.drop(index=101)
inplace=Trueの動作と注意点
inplace=Trueを指定すると対象のDataFrameを直接変更し、戻り値はNoneになります。元のサンプルを壊さないよう、コピーで確認します。
df_copy = df.copy()
return_value = df_copy.drop(index=101, inplace=True)
print("戻り値:", return_value)
print("変更後のdf_copy:")
print(df_copy)
戻り値: None
変更後のdf_copy:
商品 地域 売上 利益
100 ノートPC 東京 1200 240
102 キーボード 東京 1500 300
103 モニター 名古屋 700 140
104 USBメモリ 大阪 1100 220
return_valueはNoneですが、df_copyからはindexラベル101の行が削除されています。
次の書き方は、Noneをdfへ代入してしまうので避けてください。
df = df.drop(index=101, inplace=True) # 誤り:dfがNoneになる
初心者は、処理の結果を追いやすいdf = df.drop(...)を基本にすると安全です。
KeyErrorが出る原因と対処法
存在しない行ラベルや列名を指定すると、既定ではKeyErrorになります。ここでは、存在しない「売上高」列を指定してエラーを確認します。
try:
df.drop(columns="売上高")
except KeyError as error:
print(type(error).__name__ + ":", error)
KeyError: "['売上高'] not found in axis"
KeyErrorの確認表
| 確認項目 | よくある原因 | 確認方法 |
|---|---|---|
| 列名 | 「売上」と「売上高」などの表記違い | df.columns.tolist() |
| 行ラベル | 位置番号とindexラベルの混同 | df.index.tolist() |
| 大文字・小文字 | Salesとsalesの違い |
実際の列名を表示 |
| 前後の空白 | "売上 "のような空白 |
repr()などで確認 |
| 行・列 | axisの指定間違い |
index=・columns=を使う |
print("列名:", df.columns.tolist())
print("indexラベル:", df.index.tolist())
列名: ['商品', '地域', '売上', '利益']
indexラベル: [100, 101, 102, 103, 104]
errors=”ignore”を使ってよい場面
errors="ignore"を指定すると、存在しないラベルを無視して、存在するラベルだけを削除できます。
df_ignored = df.drop(columns=["利益", "存在しない列"], errors="ignore")
print(df_ignored)
商品 地域 売上
100 ノートPC 東京 1200
101 マウス 大阪 800
102 キーボード 東京 1500
103 モニター 名古屋 700
104 USBメモリ 大阪 1100
「利益」は削除され、「存在しない列」は無視されました。ただし、タイプミスまで見逃すため、手入力したコードのエラー回避として常用しないでください。削除候補が外部データから渡され、存在するものだけ処理したい場合など、意図が明確な場面に限定します。
行削除後のindexを振り直す
行を削除してもindexは自動で連番に戻りません。必要な場合はreset_index(drop=True)を使います。
df_after_drop = df.drop(index=[101, 103])
df_after_reset = df_after_drop.reset_index(drop=True)
print("行削除後:")
print(df_after_drop)
print("\nindexを振り直した後:")
print(df_after_reset)
行削除後: 商品 地域 売上 利益 100 ノートPC 東京 1200 240 102 キーボード 東京 1500 300 104 USBメモリ 大阪 1100 220
indexを振り直した後: 商品 地域 売上 利益 0 ノートPC 東京 1200 240 1 キーボード 東京 1500 300 2 USBメモリ 大阪 1100 220
drop=Trueを付けると、削除前のindexを新しい列として残さず、0からの連番にできます。詳しくはreset_index()でインデックスを振り直す方法をご覧ください。
drop()・dropna()・drop_duplicates()の違い
名前は似ていますが、削除する対象が異なります。
| 目的 | 使うメソッド | 代表例 |
|---|---|---|
| 指定した行・列を削除 | drop() |
df.drop(columns="利益") |
| 欠損値を含む行・列を削除 | dropna() |
df.dropna() |
| 重複行を削除 | drop_duplicates() |
df.drop_duplicates() |
| 条件に合う行だけ残す | ブール条件 | df[df["売上"] >= 1000] |
- 欠損値を削除したい場合:dropna()で欠損値を削除する方法
- 重複行を削除したい場合:drop_duplicates()で重複行を削除する方法
- 削除前に重複を確認したい場合:duplicated()で重複行を確認する方法
よくあるミス
| ミス | 起こること | 対処 |
|---|---|---|
df.drop(1)を「上から2行目」と決めつける |
indexラベル1を探す | 位置ならdf.index[1]を使う |
| 列名を指定したのに行として扱われる | KeyErrorになる |
columns="列名"を使う |
| 戻り値を保存しない | 元のdfが変わらない | 再代入する |
再代入とinplace=Trueを同時に使う |
変数がNoneになる |
どちらか一方にする |
errors="ignore"を常用する |
タイプミスを見逃す | 原則は既定のraiseで確認 |
| 行削除後に連番だと思い込む | indexが飛んだままになる | 必要ならreset_index(drop=True) |
実務例:分析に不要な列と取消データを除く
実務では、最初に不要な管理列を削除し、その後に対象外の行を除くことがあります。元データを残しながら、分析用DataFrameを作ります。
raw_df = pd.DataFrame(
{
"伝票ID": ["A001", "A002", "A003", "A004"],
"商品": ["ノートPC", "マウス", "モニター", "キーボード"],
"売上": [120000, 3000, 35000, 8000],
"状態": ["確定", "取消", "確定", "確定"],
"取込メモ": ["batch1", "batch1", "batch2", "batch2"],
}
)
cancel_index = raw_df.index[raw_df["状態"] == "取消"]
analysis_df = raw_df.drop(index=cancel_index, columns=["取込メモ"])
analysis_df = analysis_df.reset_index(drop=True)
print("処理前:")
print(raw_df)
print("\n処理後:")
print(analysis_df)
処理前: 伝票ID 商品 売上 状態 取込メモ 0 A001 ノートPC 120000 確定 batch1 1 A002 マウス 3000 取消 batch1 2 A003 モニター 35000 確定 batch2 3 A004 キーボード 8000 確定 batch2
処理後: 伝票ID 商品 売上 状態 0 A001 ノートPC 120000 確定 1 A003 モニター 35000 確定 2 A004 キーボード 8000 確定
取消行と分析に不要な「取込メモ」列が除かれ、indexも0から振り直されました。実務では、削除前後の行数やIDを確認し、必要なデータまで消していないか検証してください。
まとめ
- 行を削除する基本形は
df.drop(index=行ラベル) - 列を削除する基本形は
df.drop(columns="列名") - 複数指定はリストを渡す
drop()は位置ではなくラベルを指定する- 通常は元のDataFrameが変わらないため、結果を再代入する
inplace=Trueの戻り値はNoneKeyErrorが出たらdf.indexとdf.columnsを確認する- 行削除後に連番が必要なら
reset_index(drop=True)を使う - 欠損値には
dropna()、重複にはdrop_duplicates()を使う
まずはindex=とcolumns=を使い分け、処理前後のDataFrameと行数・列数を確認する習慣を付けましょう。
次に読みたい関連記事
- Pandas DataFrameとは?作り方・基本操作・Seriesとの違い
- pandas dropna()の使い方|欠損値を削除
- pandas drop_duplicates()の使い方|重複行を削除
- pandas reset_index()の使い方|インデックスを振り直す
- pandas 条件抽出入門|AND・OR・query
公式ドキュメント
pandasのdrop()で行を削除するにはどう書きますか?
df.drop(index=行ラベル)と書きます。複数行ならdf.drop(index=[行ラベル1, 行ラベル2])のようにリストで指定します。
pandasのdrop()で列を削除するにはどう書きますか?
df.drop(columns="列名")と書きます。複数列ならcolumns=["列名1", "列名2"]と指定します。
axis=0とaxis=1の違いは何ですか?
axis=0は行、axis=1は列です。自分でコードを書く場合は、意味が明確なindex=・columns=を使うと間違いを減らせます。
drop()を実行しても元のDataFrameに反映されないのはなぜですか?
通常のdrop()は削除後の新しいDataFrameを返し、元のDataFrameを変更しないためです。df = df.drop(...)のように再代入します。inplace=Trueも使えますが、戻り値はNoneです。
drop()・dropna()・drop_duplicates()はどう使い分けますか?
指定した行・列ならdrop()、欠損値を含む行・列ならdropna()、重複行ならdrop_duplicates()を使います。削除の目的に合うメソッドを選びましょう。
コメント