Pandasで列を削除する方法:DataFrameから列を削除する全手法
Updated on
実世界のデータソースから取得したDataFrameには、必要な列だけが含まれていることはめったにありません。CSVエクスポートにはメタデータ列が含まれ、データベースクエリは余分なフィールドを取得し、APIレスポンスにはすでにフラット化したネストデータが含まれています。意味のある分析を行う前に、不要な列を削除する必要があります。これを間違えると -- 誤って間違った列を削除したり、コピーを作成するつもりで元のDataFrameを変更してしまったり -- 追跡が困難なデータ損失バグが発生します。
Pandasは列を削除するための複数のメソッドを提供しており、それぞれ異なる状況に適しています。drop()メソッドが最も汎用性がありますが、del、pop()、列選択も便利な代替手段です。このガイドでは、各アプローチをいつ使用すべきかを明確な例で解説します。
df.drop()を使用する -- 標準的なアプローチ
drop()メソッドは列を削除する主な方法です。列名を渡してaxis=1を設定するか、columnsパラメータを使用します。
単一の列を削除する
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'salary': [50000, 60000, 70000],
'department': ['Engineering', 'Marketing', 'Sales'],
})
# 方法1:columnsパラメータを使用(推奨)
df_clean = df.drop(columns=['salary'])
print(df_clean)
# 方法2:axis=1を使用
df_clean = df.drop('salary', axis=1)複数の列を削除する
import pandas as pd
df = pd.DataFrame({
'id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie'],
'email': ['a@test.com', 'b@test.com', 'c@test.com'],
'temp_col': [None, None, None],
'internal_id': ['X1', 'X2', 'X3'],
})
# 複数の列を一度に削除
df_clean = df.drop(columns=['temp_col', 'internal_id', 'email'])
print(df_clean)
# id name
# 0 1 Alice
# 1 2 Bob
# 2 3 Charlieinplaceパラメータ
デフォルトでは、drop()は新しいDataFrameを返します。inplace=Trueを使用して元のDataFrameを変更します:
import pandas as pd
df = pd.DataFrame({'a': [1], 'b': [2], 'c': [3]})
# 新しいDataFrameを返す(元のDataFrameは変更なし)
new_df = df.drop(columns=['b'])
print(df.columns.tolist()) # ['a', 'b', 'c'](変更なし)
print(new_df.columns.tolist()) # ['a', 'c']
# 元のDataFrameを変更
df.drop(columns=['b'], inplace=True)
print(df.columns.tolist()) # ['a', 'c']errorsパラメータで存在しない列を処理する
import pandas as pd
df = pd.DataFrame({'a': [1], 'b': [2], 'c': [3]})
# デフォルト:列が存在しない場合はKeyErrorを発生
# df.drop(columns=['d']) # KeyError: "['d'] not found in axis"
# 存在しない列を無視
df_clean = df.drop(columns=['b', 'd'], errors='ignore')
print(df_clean.columns.tolist()) # ['a', 'c']del文を使用する
del文は列をその場で(in-place)削除します。簡潔ですが、一度に1列のみに制限されます。
import pandas as pd
df = pd.DataFrame({'a': [1, 2], 'b': [3, 4], 'c': [5, 6]})
del df['b']
print(df.columns.tolist()) # ['a', 'c']制限事項: 複数の列を同時に削除できません。存在しない列を無視できません(KeyErrorが発生します)。常にin-placeで変更します。
df.pop()を使用する
pop()は列を削除してSeriesとして返します。削除した列を後で使用する必要がある場合に便利です。
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'target': [1, 0],
'feature1': [10, 20],
'feature2': [30, 40],
})
# ターゲット列をDataFrameから削除しながら抽出
y = df.pop('target')
X = df
print(y)
# 0 1
# 1 0
# Name: target, dtype: int64
print(X)
# name feature1 feature2
# 0 Alice 10 30
# 1 Bob 20 40列の選択(削除の逆)
削除する列をリストアップするよりも、必要な列を選択する方が簡単な場合があります。
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'age': [25, 30],
'salary': [50000, 60000],
'dept': ['Eng', 'Mkt'],
'internal_id': ['X1', 'X2'],
})
# 特定の列のみを保持
df_clean = df[['name', 'age', 'salary']]
# それ以外のすべてを選択して列を削除
df_clean = df.loc[:, df.columns != 'internal_id']
# 条件に一致する列を保持
df_numeric = df.select_dtypes(include='number')
print(df_numeric)
# age salary
# 0 25 50000
# 1 30 60000パターンまたは条件で列を削除する
名前パターンで列を削除
import pandas as pd
df = pd.DataFrame({
'name': ['Alice'], 'age': [25],
'temp_1': [None], 'temp_2': [None],
'internal_flag': [True],
})
# 'temp_'で始まる列を削除
cols_to_drop = [c for c in df.columns if c.startswith('temp_')]
df_clean = df.drop(columns=cols_to_drop)
print(df_clean.columns.tolist()) # ['name', 'age', 'internal_flag']
# 'internal'を含む列を削除
cols_to_drop = [c for c in df.columns if 'internal' in c]
df_clean = df.drop(columns=cols_to_drop)
# filter()を使って一致する列を保持
df_temps = df.filter(like='temp') # 'temp'を含む列のみ保持
df_no_temps = df.drop(columns=df.filter(like='temp').columns)データ型で列を削除
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'age': [25, 30],
'score': [95.5, 87.3],
'active': [True, False],
})
# すべての非数値列を削除
df_numeric = df.select_dtypes(include='number')
# すべてのobject型(文字列)列を削除
df_no_strings = df.select_dtypes(exclude='object')
print(df_no_strings.columns.tolist()) # ['age', 'score', 'active']欠損値が多すぎる列を削除
import pandas as pd
import numpy as np
df = pd.DataFrame({
'a': [1, 2, 3, 4, 5],
'b': [1, np.nan, np.nan, np.nan, np.nan],
'c': [1, 2, np.nan, 4, 5],
'd': [np.nan, np.nan, np.nan, np.nan, np.nan],
})
# 50%以上の値が欠損している列を削除
threshold = len(df) * 0.5
df_clean = df.dropna(axis=1, thresh=int(threshold))
print(df_clean.columns.tolist()) # ['a', 'c']メソッド比較
| メソッド | 戻り値 | In-Place | 複数列 | 欠損列の処理 |
|---|---|---|---|---|
df.drop(columns=...) | 新しいDataFrame | 任意(inplace) | はい | errors='ignore' |
del df[col] | なし | 常に | いいえ(1列ずつ) | KeyError発生 |
df.pop(col) | 削除されたSeries | 常に | いいえ(1列ずつ) | KeyError発生 |
df[cols_to_keep] | 新しいDataFrame | いいえ | はい(逆選択) | KeyError発生 |
df.select_dtypes() | 新しいDataFrame | いいえ | dtype別 | N/A |
クリーニング済みDataFrameの可視化
列を削除してデータをクリーニングした後、PyGWalker (opens in a new tab)はJupyterで直接クリーニング済みDataFrameを探索できるインタラクティブなTableauスタイルのインターフェースを提供します:
import pygwalker as pyg
# DataFrameのクリーニング後
walker = pyg.walk(df_clean)これにより、プロットコードを書くことなく、残りの列をドラッグ&ドロップしてチャートを作成できます。
FAQ
Pandasで列を削除するには?
df.drop(columns=['列名'])を使用して列を削除し、新しいDataFrameを返します。In-place削除にはinplace=Trueを追加します。del df['列名']で素早いin-place削除、またはdf.pop('列名')で列を削除してSeriesとして返すこともできます。
複数の列を一度に削除するには?
df.drop(columns=['col1', 'col2', 'col3'])に列名のリストを渡します。これにより、指定されたすべての列が1回の操作で削除され、新しいDataFrameが返されます。
条件付き(パターンやデータ型)で列を削除するには?
名前パターンにはリスト内包表記を使用:df.drop(columns=[c for c in df.columns if c.startswith('temp_')])。データ型にはdf.select_dtypes(exclude='object')で文字列列を削除、またはdf.select_dtypes(include='number')で数値列のみを保持します。
drop()とdelの違いは?
df.drop()はデフォルトで新しいDataFrameを返し、複数の列を同時に処理でき、欠損列に対してerrors='ignore'オプションがあります。del df[col]は常にin-placeで変更し、一度に1列のみ処理し、列が存在しない場合はKeyErrorを発生させます。
欠損値のある列を削除するには?
df.dropna(axis=1)で少なくとも1つのNaNを持つ列を削除します。df.dropna(axis=1, thresh=n)で少なくともn個の非null値を持つ列のみを保持します。カスタム閾値には、null値の割合でフィルタリング:df.loc[:, df.isnull().mean() < 0.5]で欠損データが50%未満の列を保持します。
まとめ
ほとんどの状況では、df.drop(columns=[...])が正しい選択です -- 明示的で、複数の列を処理でき、デフォルトで新しいDataFrameを返します。素早いin-place単一列削除にはdelを、削除した列が必要な場合はpop()を、削除するものよりも保持するものを指定する方が簡単な場合は列選択やselect_dtypes()を使用してください。