はじめに
pythonを使って自分の家計簿を分析してみました。
昨年から自分の貯金や資産があまり増えていないため、家計の見直しをしようと思います。
分析した結果、お金が貯まっていない原因が見えると良いですが、それは難しいと思うので、分析したことを綴っていきます。
※データ分析についてはド素人なので、分析手法はあまり参考になりませんが、個人的にこういったことは趣味でやっています。
目次
- データの抽出・加工
- データの分別
- データのグラフ化
1.データの抽出・加工
まずはpandasをimportして、csvファイルから必要なカラムを抽出します。
今回のcsvファイルは、普段使っている家計簿アプリのMoney Treeからエクスポートしたものです。
期間は自分が働き始めた2019/05~2022/11/23までです。
#ライブラリのimport
import pandas as pd
data = pd.read_csv('./2022-11-23.csv', usecols=[0,1,4,6,7])
data.head()
>index,日付,金額,メモ,カテゴリ,口座名
>0,2019/05/02,-220,電車,交通,Cash Wallet
>1,2019/05/03,-470,銭湯,レジャー,Cash Wallet
>2,2019/05/02,-220,電車,交通,Cash Wallet
>3,2019/05/02,-40600,時計,買い物,Cash Wallet
>4,2019/05/03,-6300,飲み会,外食,Cash Wallet
正しく列を指定できていますね。今回必要そうな日付と金額、メモ、カテゴリ、口座名を抽出しました。
そこから、支出額を分析したいので、今回関係のないカテゴリを削除します。
#今回算出したい支出とは関係のないカテゴリを除外
data_drop_atm = data[data['カテゴリ'] != 'ATM引き出し']
data_drop_card = data_drop_atm[data_drop_atm['カテゴリ'] != 'カード返済']
data_drop_transfer = data_drop_card[data_drop_card['カテゴリ'] != '振替']
data_drop_interest = data_drop_transfer[data_drop_transfer['カテゴリ'] != '利息']
data_drop_tax = data_drop_interest[data_drop_interest['カテゴリ'] != '税金']
data_drop_dividend = data_drop_tax[data_drop_tax['カテゴリ'] != '配当金']
data_drop_pocket_money = data_drop_dividend[data_drop_dividend['カテゴリ'] != 'お小遣い']
data_drop_new_year_gift = data_drop_pocket_money[data_drop_pocket_money['カテゴリ'] != 'お年玉']
data_drop_interest_acquisition = data_drop_new_year_gift[data_drop_new_year_gift['カテゴリ'] != '利子所得']
data_drop_income = data_drop_interest_acquisition[data_drop_interest_acquisition['カテゴリ'] != '収入']
data_drop_bonus = data_drop_income[data_drop_income['カテゴリ'] != 'ボーナス']
data_drop_salary = data_drop_bonus[data_drop_bonus['カテゴリ'] != '給料']
data_drop_wituout_income = data_drop_salary
#収入も削除
data_drop_income = data_drop_income[data_drop_income['金額'] < 0]
#除外後のカテゴリを抽出
data_drop_income.groupby('カテゴリ').count().index
>Index(['WEBサービス', 'おみやげ', 'お昼', 'その他の保険', 'インターネット', 'オフィス用品', 'カフェ', 'ガス',
'コンビニ', 'サブスク', 'スポーツクラブ', 'タクシー', 'パーソナルケア', 'ホテル', 'レジャー', 'レストラン',
'レンタカー', '交通', '交際費', '住宅', '住宅設備', '保険', '医療・健康', '博物館・劇場', '外食', '学費',
'家賃', '寄付', '居酒屋・バー', '手数料', '投資', '振込手数料', '携帯電話', '教育', '映画', '未定',
'本・雑誌', '株の購入', '歯科', '水道', '水道光熱費', '消耗品', '眼科', '美容', '航空券', '衣服',
'買い物', '贈り物', '通信', '電化製品', '電気', '電車', '音楽', '食費'],
dtype='object', name='カテゴリ')
2.データの分別
対象のカテゴリを抽出できました。
続いて、月ごとの支出の合計を算出します。
対象の月を格納したmonthsを作成し、ループを回して、合計額を出します。
最初は1行1行月ごとの変数を書いていましたが、うまくfor文を活用できました。
今回はdictを使って月をkey、合計額をvalueとして値を入れていきます。
#整形後の月ごとの支出合計を算出
months = ['2019/05', '2019/06', '2019/07', '2019/08', '2019/09', '2019/10', '2019/11', '2019/12',
'2020/01', '2020/02', '2020/03', '2020/04', '2020/05', '2020/06', '2020/07', '2020/08',
'2020/09', '2020/10', '2020/11', '2020/12', '2021/01', '2021/02', '2021/03', '2021/04',
'2021/05', '2021/06', '2021/07', '2021/08', '2021/09', '2021/10', '2021/11', '2021/12',
'2022/01', '2022/02', '2022/03', '2022/04', '2022/05', '2022/06', '2022/07', '2022/08',
'2022/09', '2022/10']
data_total_by_month = {}
for month in months:
data_total_by_month[month] = -sum(data_drop_income[data_drop_income['日付'].str.startswith(month)]['金額'])
data_total_by_month.items()
>dict_items([('2019/05', 151557), ('2019/06', 66351), ('2019/07', 121205), ('2019/08', 157243),
('2019/09', 97283), ('2019/10', 88429), ('2019/11', 219016), ('2019/12', 239500), ('2020/01', 191270),
('2020/02', 170329), ('2020/03', 100085), ('2020/04', 79913), ('2020/05', 120160), ('2020/06', 181119),
('2020/07', 174341), ('2020/08', 228973), ('2020/09', 96722), ('2020/10', 112651), ('2020/11', 177236),
('2020/12', 164749), ('2021/01', 211678), ('2021/02', 350841), ('2021/03', 331282), ('2021/04', 472684),
('2021/05', 335470), ('2021/06', 311560), ('2021/07', 874986), ('2021/08', 287904), ('2021/09', 215227),
('2021/10', 178982), ('2021/11', 264887), ('2021/12', 264111), ('2022/01', 361723), ('2022/02', 192894),
('2022/03', 336010), ('2022/04', 341442), ('2022/05', 298218), ('2022/06', 345399), ('2022/07', 402846),
('2022/08', 246300), ('2022/09', 270561), ('2022/10', 224942)])
続いて、月ごとの決済回数を出していきます。
#整形後の月ごとの決済回数合計を算出
data_count_by_month = {}
for month in months:
data_count_by_month[month] = data_drop_income[data_drop_income['日付'].str.startswith(month)]['金額'].count()
data_count_by_month.items()
>dict_items([('2019/05', 72), ('2019/06', 59), ('2019/07', 68), ('2019/08', 84), ('2019/09', 71),
('2019/10', 47), ('2019/11', 55), ('2019/12', 60), ('2020/01', 67), ('2020/02', 65), ('2020/03', 72),
('2020/04', 38), ('2020/05', 47), ('2020/06', 43), ('2020/07', 53), ('2020/08', 58), ('2020/09', 51),
('2020/10', 53), ('2020/11', 75), ('2020/12', 61), ('2021/01', 77), ('2021/02', 82), ('2021/03', 73),
('2021/04', 64), ('2021/05', 59), ('2021/06', 67), ('2021/07', 60), ('2021/08', 83), ('2021/09', 78),
('2021/10', 53), ('2021/11', 69), ('2021/12', 69), ('2022/01', 79), ('2022/02', 39), ('2022/03', 54),
('2022/04', 67), ('2022/05', 71), ('2022/06', 64), ('2022/07', 87), ('2022/08', 68), ('2022/09', 82),
('2022/10', 97)])
3.データのグラフ化
それぞれ支出と決済回数のデータを出せたところで、これをグラフにしていきます。
月ごとの合計支出は棒グラフで、決済回数は折れ線グラフで描いていきます。
期間が長いため、2年ごとに区切りました。
【2019年と2020年】
import numpy as np
import matplotlib.pyplot as plt
month_count_value = []
month_total_value = []
for month in months[0:20]:
month_count_value.append(data_count_by_month.get(month))
month_total_value.append(data_total_by_month.get(month))
#月ごとの合計支出と月ごとの決済回数をグラフで表示
xline = np.array(months[0:20])
yline = np.array(month_count_value)
zline = np.array(month_total_value)
plt.rcParams['figure.figsize'] = (18 ,6)
# 棒グラフ 月毎の合計支出
fig, ax1 = plt.subplots()
plt.bar(xline, zline, color="royalblue")
ax1.set_ylabel('total outcome monthly')
# 折れ線グラフ 月毎の決済数
ax2 = ax1.twinx()
ax2.plot(xline, yline, color="crimson")
ax2.set_ylabel('count monthly')

【2021年と2022年】
month_count_value = []
month_total_value = []
for month in months[20:len(months)]:
month_count_value.append(data_count_by_month.get(month))
month_total_value.append(data_total_by_month.get(month))
#月ごとの合計支出と月ごとの決済回数をグラフで表示
xline = np.array(months[20:len(months)])
yline = np.array(month_count_value)
zline = np.array(month_total_value)
plt.rcParams['figure.figsize'] = (18 ,6)
# 棒グラフ 月毎の合計支出
fig, ax1 = plt.subplots()
plt.bar(xline, zline, color="royalblue")
ax1.set_ylabel('total outcome monthly')
# 折れ線グラフ 月毎の決済数
ax2 = ax1.twinx()
ax2.plot(xline, yline, color="crimson")
ax2.set_ylabel('count monthly')

計算してみればわかりますが、明らかに平均の支出額が2021〜2022の方が増えていますね。。
支出額と決済額に相関関係があるのか気になるので、見ていきます。
#合計支出と決済回数の相関係数を算出
df_outcome = pd.DataFrame(data_total_by_month.values(), columns=["outcome"])
df_settlement = pd.DataFrame(data_count_by_month.values(), columns=["settlement"])
df = pd.concat([df_outcome, df_settlement], axis=1)
corr = df.corr()
corr
outcome | settlement | |
outcome | 1.000000 | 0.225656 |
settlement | 0.225656 | 1.000000 |
相関関係は全然なさそうですね。
とりあえず、決済回数はあまり関係なさそうなので、気にしないで生きていきましょう。
例えば、よく毎日のカフェも塵も積もで大きな金額になると言われますが、全体で見るとそこまで影響がない気がします。
もっと優先的に気をつけるべきことがあるのでしょう。
また次回自分なりに分析してみます。