以前、NumPyの記事でも紹介したユニバーサル関数(ufunc)は、pandasオブジェクトにも適用することもできる。
コンテンツ
pandasオブジェクトにufuncを適用する
ufuncは配列の各要素にメソッドを適用することのできる関数であった。
復習も兼ねて簡単な例を見てみよう。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 5), columns=list('abcde'))
# a b c d e
# 0 -0.125719 1.049569 -0.161646 -0.104864 -1.177280
# 1 0.833952 2.061937 0.918614 1.445572 -0.277370
# 2 -0.791397 -1.115831 -2.159116 -1.248302 -0.553075
df.abs() # 絶対値を取得するabs関数
# a b c d e
# 0 0.125719 1.049569 0.161646 0.104864 1.177280
# 1 0.833952 2.061937 0.918614 1.445572 0.277370
# 2 0.791397 1.115831 2.159116 1.248302 0.553075
データフレームに対し、ufuncのabs関数を適用した例だ。
データフレームの各要素に関数が適用されていることが分かる。
列または行に対して関数を適用する
1次元配列にのみ適用することのできる関数を、データフレームの列や行に適用する場合、applyメソッドを使うと良い。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 5), columns=list('abcde'))
f = lambda x: x.max() - x.min()
df.apply(f)
# a 1.243462
# b 0.947623
# c 3.625063
# d 1.388880
# e 1.715745
# dtype: float64
この例では、一次元配列を引数にとる無名関数fを、applyメソッドをとおしてデータフレームの各列に適用している。
各列の最大値と最小値の差を配列として得ることができる。
また、applyメソッドの引数axisに軸を指定すると、指定した軸に応じて関数を適用させることができる。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 5), columns=list('abcde'))
f = lambda x: x.max() - x.min()
df.apply(f, axis=1)
# 0 1.462984
# 1 2.891210
# 2 2.264100
# dtype: float64
axisに1を指定すると、各行に対して関数が適用される。
applyメソッドの応用
applyメソッドに渡す関数は、必ずしもスカラー値を返す必要はなく、下記の例のようにシリーズを返す関数であっても良い。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 5), columns=list('abcde'))
# a b c d e
# 0 0.133877 -0.622101 0.736368 0.224072 -0.183736
# 1 0.068433 1.441126 -0.917174 0.033197 -0.403307
# 2 -1.122784 0.649132 0.668024 0.914219 1.134725
def f(x):
return pd.Series([x.max(), x.min()], index=['max', 'min'])
df.apply(f)
# a b c d e
# max 0.133877 1.441126 0.736368 0.914219 1.134725
# min -1.122784 -0.622101 -0.917174 0.033197 -0.403307
pandasオブジェクトのソート機能
pandasオブジェクトをソートする場合はsort_indexメソッドを使う。
このメソッドは、元のオブジェクトを上書きせず、新しいオブジェクトを結果として返す。
import pandas as pd
import numpy as np
df = pd.DataFrame(np.arange(15).reshape(3, 5)
, index=[1, 0, 2]
, columns=list('cbead'))
# c b e a d
# 1 0 1 2 3 4
# 0 5 6 7 8 9
# 2 10 11 12 13 14
df.sort_index()
# c b e a d
# 0 5 6 7 8 9
# 1 0 1 2 3 4
# 2 10 11 12 13 14
df.sort_index(axis=1)
# a b c d e
# 1 3 1 0 4 2
# 0 8 6 5 9 7
# 2 13 11 10 14 12
引数axisに軸を指定することもでき、軸に1を指定した場合は列ラベルによるソートがおこなわれる。
降順ソート
sort_indexはデフォルトで昇順によるソートがおこなわれるが、降順によるソートをおこなうこともできる。
df.sort_index(axis=1, ascending=False)
# e d c b a
# 1 2 4 0 1 3
# 0 7 9 5 6 8
# 2 12 14 10 11 13
値によるソート
値によるソートをおこなう場合、sort_valuesメソッドを使用する。
import pandas as pd
import numpy as np
series = pd.Series([-5, 8, 3, 1])
series.sort_values()
# 0 -5
# 3 1
# 2 3
# 1 8
series.sort_values(ascending=False)
# 1 8
# 2 3
# 3 1
# 0 -5
データフレームに対し、値によるソートを適用する場合は、オプションとして列(キー)を渡す必要がある。
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': [-5, 8, 1, 2], 'b': [3, 9, -8, -1]})
# a b
# 0 -5 3
# 1 8 9
# 2 1 -8
# 3 2 -1
df2 = df.sort_values(by='b')
print(df2)
# a b
# 2 1 -8
# 3 2 -1
# 0 -5 3
# 1 8 9
df3 = df.sort_values(by='a', ascending=False)
print(df3)
# a b
# 1 8 9
# 3 2 -1
# 2 1 -8
# 0 -5 3
複数の列(キー)によるソートをおこないたい場合、以下のようにbyオプションに配列形式で値を渡す。
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': [0, 0, 1, 1], 'b': [3, 9, -8, -1]})
# a b
# 0 -5 3
# 1 8 9
# 2 1 -8
# 3 2 -1
df2 = df.sort_values(by=['a', 'b'], ascending=[True, False])
print(df2)
# a b
# 1 0 9
# 0 0 3
# 3 1 -1
# 2 1 -8
ascendingオプションにも配列を渡すことが可能で、上記の例では第一キーは昇順、第二キーは降順によるソートをおこなっている。