学術系のデータ分析をPythonで行いました。
データを視覚化するのに便利な関数を作成したので共有します。
投稿内容は個人の見解であり、所属する組織の公式見解ではありません。
記事の対象者
今回の記事は、次の悩みを持つ人を対象に執筆しています。
- データ分析をPythonで実施したい
- 連続変数と被説明変数の関係性を可視化したい
この記事を読むうえで、必要な知識
- Pythonによるデータ分析の基礎知識を習得している
- Matplotlibの基礎知識を習得している
ざっくりとした要件定義
###作成したもの
create_graph関数
(関数名は、改善の余地があるかもしれません。)
###Input
- x軸の変数(連続変数)の列名
- y軸の変数の列名
- 対象となるDataFrame
- x値を四捨五入で切り捨てする桁数 etc
###Output
一定範囲内のx値ごとの、対象者数とy値の平均をグラフとして出力
##コード
データセットは、Airbnbが公開しているデータセットの中から、2021年9月29日時点での'Detailed Listings data for Tokyo'を使用しました。
このデータセットの中には、Airbnbに登録されている物件情報が格納されています。
なお今回の分析では、この物件情報の中の'Price'(価格)と'Reviews per month'(月ごとのレビュー値)の関係性を見ていきます。
2021年10月18日時点では、Airbnbのデータセットはこちらから誰でもダウンロードできます。
###ライブラリのインポート
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
import japanize_matplotlib
データ前処理のコード
data_dir = 'dataset/'
df=pd.read_csv(data_dir + 'listings.csv')
df_f = df[['price','reviews_per_month']]
def convert_price(df,col):
'''
airbnbの'price'列をintに変換するための関数
'''
df_temp = df[[col]].copy()
# 1文字目の'$'と最後の3文字の'.00'を削除
df_temp['temp'] = df[col].str[1:-3]
# ','を削除し、intへ変換
df_temp['temp'] = df_temp['temp'].str.replace(',', '')
df_temp['temp'] = df_temp['temp'].astype('int')
return df_temp['temp']
df_f.loc[:,'price'] = convert_price(df_f,'price')
#reviewがついていない物件を削除
df_f = df_f[df_f['reviews_per_month'].notnull()]
前処理後のoutputは次の通りです。
#code
df_f.head()
#output
_ price reviews_per_month
0 11000 1.50
1 7816 2.33
2 30000 0.78
3 14036 2.73
4 3000 0.98
#code
df_f.shape
#output
(8582, 2)
###グラフを表示するコード
def col_rounded(df,col,digit):
'''
連続値の列を四捨五入する。
四捨五入は、1の位より大きい値で行う。
ex. 百の位で切り捨てる場合、digit=3
'''
#切り捨て除算により四捨五入の切り捨てを実施
df['temp'] = df[col]//(10**digit)
df['temp'] = df['temp']*(10**digit)
return df['temp']
def df_grouped(x_col, y_col, col_min=0, col_max=float('inf'), df=df):
'''
y軸の平均のdf_mと、対象者カウントのdf_cを作成する。
'''
df_f=df[(df[x_col]>=col_min)&(df[x_col]<=col_max)]
df_m=df_f.groupby(x_col)[[y_col]].mean()
df_c=df_f.groupby(x_col)[[y_col]].count()
return df_m, df_c
def show_graph(x_col, y_col, df_m, df_c, g_width, col_min=0, col_max=float('inf'), x_label='x'):
'''
対象者数の棒グラフとyの平均の折れ線グラフを表示する。
'''
# プロットエリアを作成
fig, ax1 = plt.subplots(1,1,figsize=(10,8))
ax2 = ax1.twinx()
#対象者数の棒グラフを作成
ax1.bar(df_m.index,df_c[y_col],width=g_width, color='lightblue',label='対象者数')
#対象者数の一定範囲内での平均を作成
ax2.plot(df_m[y_col],linestyle='solid',color='k',marker='',label='平均')
#legendを作成
handler1, label1 = ax1.get_legend_handles_labels()
handler2, label2 = ax2.get_legend_handles_labels()
ax1.legend(handler1+handler2,label1+label2,loc=1)
#ラベルを作成
ax1.set_xlabel(x_label)
ax1.set_ylabel('対象者数')
ax1.grid(True)
ax2.set_ylabel('平均')
plt.title('対象者数と平均')
#グラフを表示
fig.show()
def create_graph(x_col, y_col, df, digit, col_min=0, col_max=float('inf'), x_label='x'):
'''
関数を組み合わせる。
dfを入力すると、グラフが表示される。
'''
df_temp = df.copy()
x_col_r = x_col + 'rounded'
df_temp[x_col_r] = col_rounded(df_temp,x_col,digit)
df_m, df_c=df_grouped(x_col_r, y_col, col_min, col_max,df_temp)
g_width = 10**digit - 10**(digit-1)*2
show_graph(x_col_r, y_col, df_m, df_c, g_width, col_min=col_min, col_max=col_max, x_label=x_label)
create_graph('price', 'reviews_per_month', df_f, 3, col_min=0, col_max=20000, x_label='価格')
このコードを実施すると、次のグラフが表示されます。
##まとめ
今回は、x軸が連続値である場合の視覚化方法を提案しました。
学術系のデータ分析では細かい修正が多いので、このような関数を作っておくと便利です。
興味があれば試してみてください!