Python – Pandasで列を変換する方法:mapとapplyの使い方
今回はpandasで時々使用する、mapとapplyの使い方について記載していきます。pandasは、Pythonでデータ解析を行うためのライブラリです。pandasには、データの前処理やデータの操作などを行うための様々な機能があります。今回は、pandasのmapとapplyを用いた列の変換について解説します。
1. 基本的な使い方
pandasのmapとapplyは、DataFrameやSeriesの各要素に対して、指定した関数を適用することができます。mapはSeriesに対して、applyはDataFrameに対して適用することができます。
1. mapを使った列の変換
まずは、mapを用いた基本的な使い方を見てみましょう。以下は、1列目にある数字を2倍にする例です。
In [1]: import pandas as pd
...:
...: df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
...: df['A'] = df['A'].map(lambda x: x * 2)
...: print(df)
A B
0 2 4
1 4 5
2 6 6
この例では、DataFrameのA列を取り出して、mapを用いて各要素を2倍しています。mapには、関数を引数として渡しています。ここでは、lambda式を用いて、各要素を2倍する関数を定義しています。
2. applyを使った列の変換
次に、applyを用いた基本的な使い方を見てみましょう。以下は、DataFrame全体を2倍する例です。
In [2]: df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
...: df = df.apply(lambda x: x * 2)
...: print(df)
A B
0 2 8
1 4 10
2 6 12
この例では、DataFrame全体に対して、applyを用いて各要素を2倍しています。applyには、関数を引数として渡しています。ここでは、lambda式を用いて、各要素を2倍する関数を定義しています。
2. 応用的な使い方
次に、応用的な使い方を見てみましょう。例えば、DataFrameのA列に対して、以下の条件に従って変換を行いたいとします。
- Aが1以下の場合は、’low’に変換する。
- Aが2以上かつ4以下の場合は、’mid’に変換する。
- Aが5以上の場合は、’high’に変換する。
このような場合には、以下のようにmapを用いて、関数を定義することができます。まずデータを作成します。
In [3]: df = pd.DataFrame({'A': [1, 2, 3, 4, 5, 6]})
...: df
Out[5]:
A
0 1
1 2
2 3
3 4
4 5
5 6
1. mapとlambda式
In [4]: df['A_label'] = df['A'].map(lambda x: 'low' if x <= 1 else 'mid' if x <= 4 else 'high')
...: df
Out[4]:
A A_label
0 1 low
1 2 mid
2 3 mid
3 4 mid
4 5 high
5 6 high
この例では、mapを用いて、lambda式で条件分岐を行い、A列の各要素を’low’、’mid’、’high’のいずれかに変換しています。if文をネストして、条件分岐を行っています。ここで注意したいのは、if文をネストする場合には、上から順に条件を書いていく必要があるということです。
2. applyとlambda式
次に、DataFrame全体に対して、以下の条件に従って変換を行いたいとします。
- Aが1以下の場合は、’low’に変換する。
- Aが2以上かつ4以下の場合は、’mid’に変換する。
- Aが5以上の場合は、’high’に変換する。
- Bが3未満の場合は、’low’に変換する。
- Bが3以上かつ6未満の場合は、’mid’に変換する。
- Bが6以上の場合は、’high’に変換する。
このような場合には、以下のようにapplyを用いて、関数を定義することができます。まずはデータを作成します。
In [7]: df = pd.DataFrame({'A': [1, 2, 3, 4, 5, 6], 'B': [2, 4, 6, 1, 3, 5]})
...: df
Out[7]:
A B
0 1 2
1 2 4
2 3 6
3 4 1
4 5 3
5 6 5
apply関数を使用してラベルデータを作成してみます。
In [8]: df_label = df.apply(lambda x: pd.Series(['low' if x['A'] <= 1 else 'mid' if x['A'] <= 4 else 'high',
...: 'low' if x['B'] < 3 else 'mid' if x['B'] < 6 else 'high']), axis=1)
...: df_label.columns = ['A_label', 'B_label']
...: df_label
Out[8]:
A_label B_label
0 low low
1 mid mid
2 mid high
3 mid low
4 high mid
5 high mid
この例では、applyを用いて、lambda式で条件分岐を行い、A列とB列の各要素を’low’、’mid’、’high’のいずれかに変換しています。applyには、axis=1を指定しているため、各行に対して適用されます。
まず、apply内のlambda式で、各列の値を取得し、条件分岐を行っています。pd.Seriesを用いて、変換後の値を列ごとにSeriesにまとめています。ここでも、if文をネストして、条件分岐を行っています。最後に、変換後の列を新しいDataFrameに代入しています。columns属性を用いて、列名を設定しています。
念の為、ベースdataframeとlabel dataframeをpd.concat関数を使用して、Joinして確認してみます。
In [9]: pd.concat([df, df_label], axis=1)
Out[9]:
A B A_label B_label
0 1 2 low low
1 2 4 mid mid
2 3 6 mid high
3 4 1 mid low
4 5 3 high mid
5 6 5 high mid
正しくlabelingできていますね。
3. 応用的な書き方(外部関数化)
個人的には複雑になりそうな場合は、大抵この方法を使用します。
まずは、データを作成していきます。
In [10]: df = pd.DataFrame({'A': [1, 2, 3, 4, 5, 6]})
1. mapで外部関数呼び出し
mapを用いた場合の関数の定義方法を説明します。mapに渡す関数は、1つの引数を受け取り、1つの値を返すように定義します。以下に例を示します。
In [11]: def func(x):
...: if x <= 1:
...: return 'low'
...: elif x <= 4:
...: return 'mid'
...: else:
...: return 'high'
...:
...: df['A_label'] = df['A'].map(func)
...: df
Out[11]:
A A_label
0 1 low
1 2 mid
2 3 mid
3 4 mid
4 5 high
5 6 high
この例では、引数xを受け取り、条件分岐に従って’low’または’high’を返す関数を定義しています。mapにこの関数を渡すことで、A列の各要素を変換しています。
2. applyで外部関数呼び出し
次に、applyを用いた場合の関数の定義方法を説明します。applyに渡す関数は、1つの引数を受け取り、1つの値を返すように定義します。ただし、applyを用いる場合は、DataFrameの各列や各行をSeriesとして扱うため、引数としてSeriesが渡されます。以下に例を示します。
In [14]: def func(x):
...: if x['A'] <= 1:
...: return 'low'
...: elif x['A'] <= 4:
...: return 'mid'
...: else:
...: return 'high'
...:
...: df['label'] = df.apply(func, axis=1)
...: df
Out[14]:
A label
0 1 low
1 2 mid
2 3 mid
3 4 mid
4 5 high
5 6 high
この例では、引数xにはA列とB列の値がSeriesとして渡されます。それぞれの値にアクセスするには、列名を用いてx[‘列名’]のように指定します。条件分岐に従って’low’または’high’を返す関数を定義し、applyにこの関数とaxis=1を渡すことで、DataFrame全体を変換しています。
4. まとめ
今回はPython – Pandasで列を変換する方法:mapとapplyの使い方について記載してみました。
pandasのmapとapplyを用いることで、DataFrameやSeriesの各要素に対して、指定した関数を適用することができます。基本的な使い方から応用的な使い方まで、いくつかの例を見てきました。