pandas drop()の使い方|行・列を削除するindex・columns・axisを初心者向けに解説

pandasのDataFrameから「この行だけ消したい」「この列は分析に使わないので削除したい」というときは、drop()を使います。

ただし、初めて使うと「axis=0axis=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=0axis=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

左端の100104が行の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ラベル101103の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ラベル101103の行と、「利益」列が同時に削除されています。

axis=0とaxis=1の違い

labelsaxisを組み合わせる書き方もあります。

axis 対象 indexcolumnsで書く場合
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ラベル101103が削除されました。

同じ結果は「売上が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_valueNoneですが、df_copyからはindexラベル101の行が削除されています。

次の書き方は、Nonedfへ代入してしまうので避けてください。

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()
大文字・小文字 Salessalesの違い 実際の列名を表示
前後の空白 "売上 "のような空白 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]

よくあるミス

ミス 起こること 対処
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の戻り値はNone
  • KeyErrorが出たらdf.indexdf.columnsを確認する
  • 行削除後に連番が必要ならreset_index(drop=True)を使う
  • 欠損値にはdropna()、重複にはdrop_duplicates()を使う

まずはindex=columns=を使い分け、処理前後のDataFrameと行数・列数を確認する習慣を付けましょう。

次に読みたい関連記事

公式ドキュメント

▲ ページトップへ戻る

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()を使います。削除の目的に合うメソッドを選びましょう。

コメント

タイトルとURLをコピーしました