・お題:DataFrameのデータを使って、集計など、何らか計算したい。
・DataFrameが与えられて、何等か計算したいとする。そのような場合には、pandasのapplyメソッドが便利。
・まずはデータセットを作成する。
import numpy as np
import pandas as pd
a=np.random.normal(2,2,100)
b=np.random.randint(1,101,100)
df=pd.DataFrame({"A":a,"B":b})
これでdfの中身は以下になる。
・例えば、変数ごとに合計値を算出したい場合、dfの後にくっつけるとうまくいく。
df.sum()
で以下が返ってくる。
A 190.177445
B 5577.000000
dtype: float64
簡単な処理かつ変数に対して実施するだけなら、これでも問題ない。
・例えば、各変数をすべて二乗したい場合、関数を定義してapplyメソッドに渡すと良さそう。
def func(x):
return x**2
df.apply(func)
これで、以下が返ってくる。
なんだかできてそう。
・関数を作成するには、defではなくlambdaを使うこともできる。
func = lambda x: x**2
・次に、列または行で集計する場合を考える。今回は変則的に、列または行の最大値から最小値を引いてみる。
func2 = lambda x:max(x)-min(x)
として関数を定義し、
df.apply(func2)
とすれば、
A 7.826449
B 99.000000
dtype: float64
が返ってくる。
列ごとに最大値から最小値を引いた値が返ってきた。
・行ごとに同じ処理をしたいのであれば、引数にaxis=1を追加する。
df.apply(func2,axis=1)
とすると
0 56.235408
1 2.688923
2 56.958441
3 29.874747
4 46.927073
...
95 92.124378
96 18.656672
97 61.557063
98 52.953695
99 85.004783
Length: 100, dtype: float64
が返ってきた。
・これを新たな変数としてdfに追加したいのであれば、列名を指定してそのまま放り込めば良いみたい。
df["C"]=df.apply(func2,axis=1)
とすると、
が返ってきた。確かにC列がくっついている。
・次に、文字列の変数列Dが含まれるdataframeの集計を考える。
d=np.repeat(["a","b","c","d"],25)
df2=pd.DataFrame({"A":a,"B":b,"D":d})
df2は以下になる。
・df2にapply関数でfuncを適用すると、型のエラーが返ってくる。D列の二乗が計算できないみたい。df2.drop("D",axis=1)で数字以外の列を落としてから計算させても良いけれど、少し面倒に感じる。
・数字でないものをNaNに変換してから、funcすれば、エラーは一応回避できる。数字でないものをNaNに変換するには、pd.to_numeric(対象, errors="coerce")を使えばよいので、これを関数化してapplyでdataframe全体に適用すれば良い。
nume=lambda x :pd.to_numeric(x, errors="coerce")
df2.apply(nume)
D列が絶滅した。仮にD列に数字が入っていれば、きっと生き残っただろう。この状態ならfuncやfunc2を適用してもエラーが出ない。
・dataframe全体から非数字を潰して集計するのは使えそう。
おわり