Pandasで条件に基づいて新しい列を作成

プログラミング

Pandasにおける条件に基づく新しい列の作成

Pandasライブラリは、Pythonでデータ分析を行う上で不可欠なツールです。その中でも、既存のデータフレームの列を基に、特定の条件を満たす行に対して新しい列を作成する機能は、データの前処理や特徴量エンジニアリングにおいて非常に強力な手法となります。ここでは、この条件に基づく新しい列の作成方法について、様々なアプローチとその応用例を掘り下げていきます。

基本的なアプローチ

条件に基づいて新しい列を作成する最も基本的な方法は、`apply()` メソッドとラムダ関数を組み合わせる、あるいは `loc` や `where` などのインデクサを利用することです。

apply() メソッドとラムダ関数

`apply()` メソッドは、データフレームの行または列に対して、指定した関数を適用するための汎用的なメソッドです。ラムダ関数と組み合わせることで、簡潔かつ柔軟に条件分岐を実装できます。

例えば、ある数値列 `score` が60点以上であれば「合格」、そうでなければ「不合格」という新しい列 `result` を作成したい場合を考えます。

“`python
import pandas as pd

data = {‘name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’],
‘score’: [85, 55, 70, 40]}
df = pd.DataFrame(data)

df[‘result’] = df[‘score’].apply(lambda x: ‘合格’ if x >= 60 else ‘不合格’)
print(df)
“`

このコードでは、`df[‘score’]` の各要素 `x` に対して、`x >= 60` という条件を評価し、真であれば「合格」、偽であれば「不合格」を返しています。

locインデクサ

`loc` インデクサは、ラベルやブール配列を用いてデータフレームの行や列を選択する際に使用されます。条件を満たす行に対して、直接値を代入する形で新しい列を作成することができます。

先ほどの例を `loc` を用いて実装すると以下のようになります。

“`python
df[‘result’] = ‘不合格’ # まずデフォルト値を設定
df.loc[df[‘score’] >= 60, ‘result’] = ‘合格’
print(df)
“`

この方法では、まず全ての行の `result` 列をデフォルト値(ここでは「不合格」)で初期化しておき、その後、`df[‘score’] >= 60` という条件を満たす行の `result` 列のみを「合格」に上書きしています。これは、複数の条件がある場合に、それぞれの条件で上書きしていくというアプローチも可能です。

where() メソッド

`where()` メソッドは、指定した条件を満たす要素はそのままにし、満たさない要素を指定した値で置き換えます。この逆の動作をする `mask()` メソッドと合わせて理解すると便利です。

`where()` を使用した例:

“`python
df[‘result’] = df[‘score’].where(df[‘score’] >= 60, ‘不合格’)
df[‘result’] = df[‘result’].mask(df[‘result’] != ‘不合格’, ‘合格’) # 条件を満たすものを「合格」に
print(df)
“`

この例では、まず `where()` を使って、60点未満の要素を「不合格」に置き換えています。その後、`mask()` を使って、「不合格」ではない要素(つまり60点以上の要素)を「合格」に置き換えています。

複数の条件に基づく列の作成

複数の条件を組み合わせたい場合、`np.select()` 関数や、`loc` と論理演算子 (`&`、`|`、`~`) を用いる方法が一般的です。

np.select()

NumPyの `select()` 関数は、複数の条件とそれに対応する値をリストで指定することで、複雑な条件分岐を効率的に記述できます。

“`python
import numpy as np

data = {‘score’: [85, 55, 70, 40, 95, 30]}
df = pd.DataFrame(data)

conditions = [
df[‘score’] >= 90,
(df[‘score’] >= 70) & (df[‘score’] = 60) & (df[‘score’] < 70),
df['score'] < 60
]
choices = ['A', 'B', 'C', 'D']

df['grade'] = np.select(conditions, choices, default='Unknown')
print(df)
“`

このコードでは、成績の評価(A, B, C, D)を、点数に基づいて段階的に設定しています。`conditions` リストには各条件を、`choices` リストには対応する値を定義します。`default` 引数で、どの条件にも一致しなかった場合の値を指定できます。

locと論理演算子

`loc` インデクサと論理演算子 (`&`:AND、`|`:OR、`~`:NOT) を組み合わせることで、複数の条件を表現することも可能です。

“`python
df[‘result’] = ‘不合格’
df.loc[df[‘score’] >= 60, ‘result’] = ‘合格’

# さらに、80点以上なら「優秀」という条件を追加
df[‘result’] = np.where(df[‘score’] >= 80, ‘優秀’, df[‘result’])
print(df)
“`

この例では、まず「合格」「不合格」を決定し、その後、80点以上という追加条件で「優秀」に上書きしています。この `np.where()` は、`if-else` のような操作をベクトル化して高速に実行します。

応用例と注意点

条件に基づく新しい列の作成は、以下のような様々な場面で活用されます。

* カテゴリ変数の作成:数値データを一定の範囲で区切ってカテゴリに分類する。
* フラグ列の作成:特定の条件を満たす行に1、それ以外に0といったフラグを立てる。
* 特徴量エンジニアリング:既存のデータから新しい特徴量を作成し、機械学習モデルの性能を向上させる。

注意点としては、条件が複雑になりすぎるとコードの可読性が低下する可能性があるため、`np.select()` のような関数を利用したり、処理を分割したりすることが推奨されます。また、データ型の一貫性にも注意が必要です。新しい列に異なるデータ型の値を混在させると、予期せぬエラーの原因となることがあります。

まとめ

Pandasで条件に基づいて新しい列を作成する方法は多岐にわたります。`apply()`、`loc`、`where()` といった基本的なメソッドから、`np.select()` のようなより高度な関数まで、状況に応じて最適な手法を選択することが重要です。これらの機能を使いこなすことで、データ分析の効率と質を大きく向上させることができるでしょう。