以前、NumPyの記事でも紹介したユニバーサル関数(ufunc)は、pandasオブジェクトにも適用することもできる。
Contents
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オプションにも配列を渡すことが可能で、上記の例では第一キーは昇順、第二キーは降順によるソートをおこなっている。