いろいろ倉庫

KNIME、EXCEL、R、Pythonなどの備忘録

【Python】データで計算したい

・お題: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全体から非数字を潰して集計するのは使えそう。

 

おわり