Pythonライブラリ講座

map・applyを解説!Pandasのmapでデータを置換する

前のページ|次のページ

16章では『mapメソッドによる要素の置換』『map/applyメソッドによる各要素に対する関数の適用』について解説します。

本記事を読めばmapとapplyの基本的な使い方をマスターできます。

ぜひ最後まで読んでいってください!

本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。

NumPyPandasMatplotlibScipySeabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。

さらに、学習した内容を定着させられるように各章演習問題を用意しています。

・Pythonでデータ分析ができるようになりたい

・Pythonの基礎事項は一通り学んだので、さらに深く学びたい

このように考えている方はTech Teacherが運営する【Python ライブラリ編】で、Pythonによるデータサイエンスの学習をすることをお勧めします!

なお、『Pythonについて全く知らない』・『Pythonの基礎事項がまだ分かっていない』という方は、まずコチラの【Python 基礎編】で基礎を一通り学習してからライブラリ編に取り掛かりましょう!

<ライブラリ編 目次>

<ライブラリの基礎>
1章:ライブラリとは

<NumPy>
2章:NumPyの概要と配列(ndarray)
3章:統計量や次元の取得/ソート
4章:配列のインデックス
5章:numpy.whereによる条件制御
6章:配列の結合/分割
7章:乱数

<SciPy>
8章:SciPyの概要と基本操作

<Pandas>
9章:SeriesDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い

<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース

<Seaborn>
21章:Seabornの概要と基本操作

mapメソッド

列(Series)の要素を置換

map』メソッドを用いて、Seriesの要素を置換することができます。

こちらはExcelのvlookup関数に似たような機能です。

Series.map(辞書型の参照データ)

mapメソッドの引数として辞書を渡すと、辞書のキーと一致する要素を辞書の値で置換します。

具体例を見てみましょう。

まずは元となるデータを用意します。

#元データ
sr = pd.Series(['Python', 'Java', 'C#', 'JavaScript', 'Python'])
sr
0        Python
1          Java
2            C#
3    JavaScript
4        Python
dtype: object

次に、要素を置換する際の参照データを辞書形式で定義します。

#「Python」は「Python」、「C#」は「CSharp」、「JavaScript」は「JS」に対応
name_map = {
    'Python':'Python',
    'C#':'CSharp',
    'JavaScript':'JS'
}

以下のコードでは、「name_map」を参照して先ほど定義したSeries「sr」の要素を置換しています。

#name_mapを参照して要素を置換
sr.map(name_map)
0    Python
1       NaN
2    CSharp
3        JS
4    Python
dtype: object

作成した参照データに基づいて、

・Python → Python
・C# → CSharp
・JavaScript → JS

のように要素が置換されていることが分かると思います。

参照データのキーに出現しない要素は、NaNに置換されます。

また以下の例のように既存のDataFrameにおいて、ある列を参照して新たな列を追加したいときに使用する場合も多いです。

# 元のデータフレームを作成
data = {
    'Fruits': ['apple', 'banana', 'strawberry', 'orange', 'pineapple', 'apple'],
    'Country': ['Japan', 'Philippines', 'Japan', 'Spain', 'Thailand', 'Japan']
}
df = pd.DataFrame(data)

df
DataFrame1
#参照データ
price_map = {
    'apple':100,
    'banana':200,
    'strawberry':800,
    'orange':300,
    'pineapple':1000
}

#Fruits列を利用して新たにPrice列を作成
df['Price'] = df['Fruits'].map(price_map)
df
DataFrame2

SeriesやDataFrameに任意の関数を適用

map』メソッドのもう一つの使い方として、SeriesやDataFrameの各要素に任意の関数を適用することができます。

SeriesまたはDataFrame.map(関数名)

とすると、SeriesやDataFrameの各要素に指定した関数の処理を適用できます。

まずは元データを準備します。

#元データを定義
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Age': [25, 30, 35, 40, 45],
    'Gender': ['Female', 'Male', 'Male', 'Male', 'Female'],
    'Occupation': ['Engineer', 'Designer', 'Manager', 'Engineer', 'Data Scientist'],
    'Salary': [60000, 75000, 90000, 80000, 100000]
}

df = pd.DataFrame(data)

df
DataFrame3"

このデータの「Salary」列の各要素に10000を加算してみます。

mapによって適用する関数として、「my_func」を定義します。

def my_func(x):
    return x + 10000

この関数を「Salary」列の各要素に適用するコードは以下のようになります。

#Salary列の各要素にmy_funcを適用
df['Salary'].map(my_func)
0     70000
1     85000
2    100000
3     90000
4    110000
Name: Salary, dtype: int64

「Salary」列の各要素に10000を加算したSeriesが得られました。

得られたSeriesで元のデータの列を置き換えたい場合は、以下のように書きます。

#Salary列の各要素にmy_funcを適用
df['Salary'] = df['Salary'].map(my_func)
df
DataFrame4

また、同じ処理を『無名関数(ラムダ式)』を用いて行うコードは以下のように書けます。

#無名関数を用いる場合
df['Salary'] = df['Salary'].map(lambda x: x + 10000)
df
DataFrame5

先ほどのコードに続いて実行すると10000が2回加算されて上記とは異なる結果が得られるので、注意してください。

無名関数(ラムダ式)』については以下の記事で説明しています。

初めて聞いた方は参照してみてください。

DataFrameにmapメソッドを使用して各要素に関数を適用することもできます。

以下の例では、新たに定義したDataFrame「df」の各要素に10をかけています。

import numpy as np

df = pd.DataFrame(np.arange(9).reshape(3,3))
#   0  1  2
#0  0  1  2
#1  3  4  5
#2  6  7  8

df.applymap(lambda x: x * 10)
DataFrame5

Pandasのバージョンによっては上記の例のようにmapメソッドではなくapplymapメソッドを使用する必要があります。

applyメソッド

apply』メソッドを用いると、SeriesやDataFrameに任意の関数を適用することができます。

基本的な使い方はmapメソッドで関数を渡す場合と同様です。

まずは元データを準備します。

#元データを定義
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Age': [25, 30, 35, 40, 45],
    'Gender': ['Female', 'Male', 'Male', 'Male', 'Female'],
    'Occupation': ['Engineer', 'Designer', 'Manager', 'Engineer', 'Data Scientist'],
    'Salary': [60000, 75000, 90000, 80000, 100000]
}

df = pd.DataFrame(data)

df
DataFrame3

この「df」の「Salary」列に自作関数my_funcを適用してみましょう。

def my_func(x):
    return x + 10000

#my_funcをSalary列に適用
df['Salary'].apply(my_func)
0     70000
1     85000
2    100000
3     90000
4    110000
Name: Salary, dtype: int64

mapを使用した場合と同じ結果が得られました。

また、DataFrameに対しても同様の処理を行うことができます。

import numpy as np

df = pd.DataFrame(np.arange(9).reshape(3,3))
#   0  1  2
#0  0  1  2
#1  3  4  5
#2  6  7  8

df.apply(lambda x: x * 10)
DataFrame5

16章の練習問題

以下の練習問題を解いてみましょう。

練習問題

問1. 以下のコードで定義されるDataFrame「df」について、(1)~(2)の問いに答えてください。

#元データを定義
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Age': [25, 30, 35, 40, 45],
    'Gender': ['Female', 'Male', 'Male', 'Male', 'Female'],
    'Occupation': ['Engineer', 'Designer', 'Manager', 'Engineer', 'Data Scientist'],
    'Salary': [60000, 75000, 90000, 80000, 100000]
}

df = pd.DataFrame(data)

df

(1) dfのGender列の’Felame’を’F’に、’Male’を’M’に置換してください。
(2) (1)で作成したDataFrameについて、Name列の各要素の先頭1文字を抜き出してください。

問2. 問1で最初に定義したdfに対して、次の問いに答えてください。

Salary列の各要素をそれぞれ10倍した、新たなDataFrameを作成してください。

解答

問1(クリックして解答を表示)

(1)

#(1)
gender_map = {
    'Female':'F',
    'Male':'M'
}

df['Gender'] = df['Gender'].map(gender_map)
df
DataFrame6

(2)

#(2)
df['Name'].map(lambda x: x[0])
0    A
1    B
2    C
3    D
4    E
Name: Name, dtype: object

問2(クリックして解答を表示)

#元データを定義
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Age': [25, 30, 35, 40, 45],
    'Gender': ['Female', 'Male', 'Male', 'Male', 'Female'],
    'Occupation': ['Engineer', 'Designer', 'Manager', 'Engineer', 'Data Scientist'],
    'Salary': [60000, 75000, 90000, 80000, 100000]
}

df = pd.DataFrame(data)

df['Salary'] = df['Salary'].apply(lambda x: x * 10)
df
DataFrame7

次のページへ

Pandas初心者必見!欠損値の処理をマスターしよう 前のページ|次のページ 17章ではPandasにおける欠損値の判定方法として『isnull/isnaメソッド』の使い方を紹介しま...