Python: Plotlyを用いた記述統計の手法①
日経ソフトウェア2022年9月号に載っていた、Plotlyを用いた記述統計の手法を自分用のメモとして記事にして見ました。
データの内容を確認
pip install plotly
import pandas as pd
import plotly.express as px
df = pd.read_csv("baseball_players.csv")
#データの行の内容と形状を確認する
#内容は架空のプロ野球チームの選手一覧
df.info()
df.shape
ヒストグラムを描写
#plotlyの機能を使ってヒストグラムを描写する
fig = px.histogram(df, x="height", nbins=20, barmode="overlay")
fig.show()
統計量をハードコーディングで求める
Plotlyで読み込んだデータの統計量をライブラリではなく、あえてハードコーディングで求める
#身長の平均 = 合計 / リストの数を求める
sum(df["height"]) / len(df["height"])
#身長の中央値を求める。Pythonのみだと若干記述が面倒
sorted_list = sorted(df["height"])
#リストを昇順に並び替える
#リストの数を確認。偶数・奇数の場合で処理を変える
if len(sorted_list) % 2 ==0:
median = (sorted_list[(len(sorted_list)//2) - 1] + sorted_list[len(sorted_list)//2]) / 2
print(median)
elif len(sorted_list) % 2 ==1:
median = sorted_list[len(sorted_list)//2]
print(median)
#データのバラツキ=分散、標準偏差を求める
#平均→偏差→分散→標準偏差
#偏差 = 各データの値 - 全データの平均
#分散 = 偏差の2乗和 / データの個数
#標準偏差 = √分散
#平均
avg = sum( df["height"] / len(df["height"]))
#偏差の2乗和
s=0
for i in range(len(df["height"])):
s += (df["height"][i] - avg)**2
#分散 - 偏差の2乗和をデータの個数で割る
var = s / (len(df["height"]))
#標準偏差
sigma = var ** (1/2)
print(f"分散:{var}")
print(f"標準偏差:{sigma}")
要素ごとに統計量・ヒストグラムを描く
#groupbyを使って要素ごとに分けて計算する
grouped = df.groupby("JPNorNot")
print(grouped["height"].var(ddof=0))
print(grouped["height"].std(ddof=0))
#要素ごとに分けて身長のヒストグラムを描写する
fig = px.histogram(df, x="height", nbins=50, color="JPNorNot" , barmode="overlay")
fig.show()
箱ひげ図・散布図を描く
#箱ひげ図
fig = px.box(df, x="JPNorNot",y="height" , color="JPNorNot")
fig.show()
#散布図
fig = px.scatter(df, x="height", y="weight")
fig.show()
相関係数をハードコーディングで求める
#身長と体重の相関係数を求める
x = df["height"]
y = df["weight"]
#平均値の算出
avg_x = sum(x)/len(x)
avg_y = sum(y)/len(y)
#変数の初期化
sxx, syy, sxy = [0,0,0]
#平方和を算出
for i in range(len(df)):
sxx += (x[i]-avg_x)**2
syy += (y[i]-avg_y)**2
sxy += (x[i]-avg_x)*(y[i]-avg_y)
#相関係数 - x,y,の共分散をお互いの標準偏差で割る
r = (sxy/len(df)) / ( (sxx/len(df))**(1/2) * (syy/len(df))**(1/2) )
print(r)
Pandasで統計量を求める
Pandasを用いれば平均値、中央値、分散、標準偏差、不偏分散、不偏標準偏差、相関係数といった統計量をすぐに弾き出すことができる
#Pandasで統計量を求める
#平均値、中央値、分散、標準偏差、不偏分散、不偏標準偏差、相関係数
print(df["height"].mean())
print(df["height"].median())
print(df["height"].var(ddof=0))
print(df["height"].std(ddof=0))
print(df["height"].var())
print(df["height"].std())
print(df[["height","weight"]].corr().at["height","weight"])
フォルダー内の複数データを結合する
#複数のデータを結合して処理する練習
import pandas as pd
import glob
import plotly.express as px
import datetime
files = glob.glob("./expenses/*.csv")
df = pd.DataFrame()
#ファイルの数だけデータを結合する。これでフォルダ内のデータ全てを1つに纏められる
for file in files:
tmp = pd.read_csv(file, encoding="S-JIS")
df=pd.concat([df,tmp])
#データの行の内容と形状を確認する
#内容は架空のプロ野球チームの選手一覧
df.info()
df.shape
データの前処理
#データの前処理
#①分析に不要な列を削除
#②カラム名を英語に変更
#③不要なデータを除外する
# 分析に不要な列を削除する
df=df.drop(['計算対象','内容','保有金融機関','メモ','振替','ID'],axis=1)
# カラム名を英語に変更する
df.columns=['date','amount','item','sub_item']
# 支出データの抽出
## 取引金額が負のデータを取り出す
df=df[df['amount']<0]
## 正負を逆転させる
df['amount']=-1*df['amount']
## 不要なデータを除外する
df=df[df['item'] != '現金・カード']
df=df[df['item'] != '住宅']
df=df[df['item'] != '未分類']
# 日時カラムの追加
## dateカラムの型を変更する
df['date']=pd.to_datetime(df['date'])
df['month']=df['date'].dt.month
df['week']=df['date'].dt.isocalendar().week
df['dow']=df['date'].dt.dayofweek
# カラムの整頓
df=df.reindex(columns=['date', 'month','week', 'dow','item','sub_item','amount'])
# 取引日順に並び替える
df=df.sort_values('date')
print(df.info) # データの内容とサイズの確認
print(df.dtypes) # 変数の型の確認
#describeを用いると要約統計量を出力できる
print(df["amount"].describe())
各コラムの箱ひげ図を描く
#各コラムの箱ひげ図を描く
fig = px.box(df, x="month", y="amount", color="month")
fig.show()
各コラムの2データ間の散布図を描く
# 縦持ちを横持ちに変換する
pivot_df = df.pivot_table(values=['amount'], index=['week'], columns=['item'], aggfunc='sum')
# 欠損部分にゼロを代入する
pivot_df=pivot_df.fillna(0)
# multi indexを解除する
pivot_df.columns=pivot_df.columns.droplevel(0)
# データの先頭5行を表示する
pivot_df.head()
#各コラムの2データ間の散布図を描く
fig = px.scatter_matrix(pivot_df, dimensions=pivot_df.columns)
fig.show()
各コラムの2データ間の相関係数を描く
#各コラムの2データ間の相関係数を描く
corr = pivot_df.corr()
corr
fig = px.imshow(corr, text_auto = True)
fig.show()
次回は日経ソフトウェア2022年10月号に掲載される予定の記述統計・後編の学習を目指します。頑張りますね。