pandasで要素、行、列に関数を適用するmap, applymap, apply

適用する関数、対象による違い

pandasのオブジェクト(pandas.DataFrame, pandas.Series)に関数を適用する場合、どんな関数を適用するか、要素・行・列のいずれに適用するかによって、使うメソッドなどが異なる。

NumPyの関数の引数にpandasオブジェクトを指定 関数の引数にpandasオブジェクトを指定可能 関数の種類および引数の設定によって要素・行・列いずれに適用されるかが異なる pandasオブジェクトのメソッドとして用意されている関数もある

pandasオブジェクトのメソッドで関数を適用 要素(スカラー値)に対する関数 Seriesの各要素に適用: map(), apply() DataFrameの各要素に適用: applymap()

行・列(一次元配列)に対する関数 DataFrameの各行・各列に適用: apply()

今回は以下のcsvファイルを読み込んで例を示す。 a,b,c,d 11,12,13,14 21,22,23,24 31,32,33,34

import pandas as pd
import numpy as np

df = pd.read_csv('data/src/sample_header.csv')
print(df)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

NumPyの関数の引数にpandasオブジェクトを指定

NumPyの関数の引数にpandasオブジェクトを指定することができます。 要素に適用 NumPyのユニバーサル関数(ufunc: 配列の要素に適用される関数)はpandasオブジェクトの各要素に適用される。 絶対値(fabs())や平方根(sqrt())、log(log())など。

Universal functions (ufunc) — NumPy v1.13 Manual

print(np.sqrt(df))
#           a         b         c         d
# 0  3.316625  3.464102  3.605551  3.741657
# 1  4.582576  4.690416  4.795832  4.898979
# 2  5.567764  5.656854  5.744563  5.830952

行・列に適用 NumPy配列の要素全体から値を算出する関数の引数にpandasオブジェクトを指定すると、デフォルトではpandasオブジェクトの各列に対して適用される。引数axis=1とすると各行に対して適用される。 最大(amax())や最小(amin())、平均(mean())など。

print(np.amax(df))
# a    31
# b    32
# c    33
# d    34
# dtype: int64

print(np.mean(df, axis=1))
# 0    12.5
# 1    22.5
# 2    32.5
# dtype: float64

(おまけ)pandas.DataFrame、pandas.Seriesのメソッド 最大、最小、平均、分散などはpandasオブジェクトのメソッドとしても準備されているので、そちらを使ってもいい。その他のメソッドについては以下のリンク参照。

API Reference — pandas 0.21.0 documentation

この場合も、デフォルトでは各列に対して適用され、引数axis=1とすると各行に対して適用される。

print(df.max())
# a    31
# b    32
# c    33
# d    34
# dtype: int64

print(df.max(axis=1))
# 0    14
# 1    24
# 2    34
# dtype: int64

pandasオブジェクトのメソッドで関数を適用

pandasオブジェクトのメソッドを使って要素や行・列に関数を適用することが可能。Pythonの組み込み関数、自分で定義した関数を適用できます。NumPyの関数も問題ありません。

Seriesの各要素に適用: map(), apply() DataFrameの各要素に適用: applymap() DataFrameの各行・各列に適用: apply()

いずれのメソッドも、処理された新たなpandasオブジェクトを返し、元のオブジェクトは変更されない。dropna()やfillna()にあるような引数inplaceは存在しないので、元のオブジェクト自体を変更したい場合は、

df = df.applymap(function)

のように、新たなオブジェクトを元のオブジェクトに代入して上書きします。

Seriesの各要素に関数を適用: map(), apply()

Pythonの組み込み関数、無名関数(lambda)やdefで定義した関数をmap()またはapply()の引数に渡す。

s = df['a']
print(s)
# 0    11
# 1    21
# 2    31
# Name: a, dtype: int64

f_brackets = lambda x: '[{}]'.format(x)
print(s.map(f_brackets))
# 0    [11]
# 1    [21]
# 2    [31]
# Name: a, dtype: object

def f_str(x):
    return str(x).replace('1', 'One').replace('2', 'Two').replace('3', 'Three').replace('4', 'Four')

print(s.map(f_str))
# 0      OneOne
# 1      TwoOne
# 2    ThreeOne
# Name: a, dtype: object

map()の場合、引数に辞書dictを指定すると要素の置換となります。詳細は以下の記事を参照。

また、文字列に対する置換などの処理は文字列メソッドとして用意されています。

DataFrameの各要素に関数を適用: applymap()

Pythonの組み込み関数、無名関数(lambda)やdefで定義した関数をapplymap()の引数に渡す。

f_oddeven = lambda x: 'odd' if x % 2 == 1 else 'even'
print(df.applymap(f_oddeven))
#      a     b    c     d
# 0  odd  even  odd  even
# 1  odd  even  odd  even
# 2  odd  even  odd  even

DataFrameの各行・各列に適用: apply()

一次元配列に適用可能な関数をapply()の引数に渡す。デフォルトでは各列に対して適用され、引数axis=1とすると各行に対して適用される。

f_maxmin = lambda x: max(x) - min(x)
print(df.apply(f_maxmin))
# a    20
# b    20
# c    20
# d    20
# dtype: int64

print(df.apply(f_maxmin, axis=1))
# 0    3
# 1    3
# 2    3
# dtype: int64

DataFrameの特定の行・列の要素に適用

DataFrameの特定の行・列の要素にのみ関数を適用するメソッドはないので、

行・列を選択し、Seriesとしてmap()またはapply()で関数を適用 元の行・列に代入して上書き

という処理を行う。

df['b'] = df['b'].map(f_str)
print(df)
#     a         b   c   d
# 0  11    OneTwo  13  14
# 1  21    TwoTwo  23  24
# 2  31  ThreeTwo  33  34

df.iloc[2] = df.iloc[2].map(f_str)
print(df)
#           a         b           c          d
# 0        11    OneTwo          13         14
# 1        21    TwoTwo          23         24
# 2  ThreeOne  ThreeTwo  ThreeThree  ThreeFour

シェア

関連カテゴリー

Python pandas

『Python Data Science Handbook』(英語の無料オンライン版あり) pandasで行・列の差分・変化率を取得するdiff, pct_change pandasのMultiindexの指定・追加・解除・ソート・レベル変更 pandas.DataFrame, SeriesとNumPy配列ndarrayを相互に変換 pandasの時系列データにおける頻度(引数freq)の指定方法 pandasの時系列データのタイムゾーンを処理(tz_convert, tz_localize) pandas.DataFrameから特定の型dtypeの列を抽出(選択) pandasのピボットテーブルでカテゴリ毎の統計量などを算出 pandasの文字列を区切り文字や正規表現で複数の列に分割 pandas.DataFrameのforループ処理(イテレーション) pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと) pandas.DataFrameに列や行を追加(assign, appendなど) pandas.DataFrameの行番号、列番号を取得 pandasでExcelファイル(xlsx, xls)の書き込み(to_excel) pandas.DataFrameから条件を満たす行名・列名の行・列を抽出(選択)

Last Updated: 6/26/2019, 10:34:03 PM