Python – Pandasで列を変換する方法:mapとapplyの使い方

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の各要素に対して、指定した関数を適用することができます。基本的な使い方から応用的な使い方まで、いくつかの例を見てきました。

(Visited 23 times, 1 visits today)