時間のデータを扱う時は、resample()
が便利です。
resample()
とは 頻度変更 を行うためのDataFrameのメソッドです。頻度変更には、次の2種類があります。
- アップサンプリング: より高い頻度への変更(月単位のデータを日単位に変換する、など)。補完方法を指定する。
- ダウンサンプリング: より低い頻度への変更(日単位のデータを月単位に変換する、など)。集約方法を指定する。
このうち、ダウンサンプリングの処理はgroupby()
を使った集約と似ています。
本問では、groupby()
の代わりにresample()
で集約を行う方法を学びます。
resample()を使った集約
resample()
は、インデックスが日付時刻型のDataFrameで使えます。次のように 頻度を表す文字列 (月単位なら"M"
、日単位なら"D"
など)を指定して集約メソッドと組み合わせると、指定した単位で集約を行います。
df.resample(頻度を表す文字列).集約メソッド()
たとえば「月ごとに合計を集約する」場合、次のように記述します。
# 月ごとに合計を集約する("M"は月を表す)
df.resample("M").sum()
「頻度を表す文字列」には、次のような文字列が指定可能です。
文字列 | 単位 | 文字列 | 単位 |
---|---|---|---|
"S" | 秒 | "W" | 週(月曜始まり) |
"T" | 分 | "M" | 月 |
"H" | 時間 | "Q" | 四半期(※) |
"D" | 日 | "Y" | 年 |
※ 四半期とは1年を3か月単位に分けて4分割したもので、企業の売上を期ごとに比較する時などに使用されます。pandasでは、1/1〜3/31、4/1〜6/30、7/1〜9/30、10/1〜12/31の期間で分けられます。
演習
まずは、今回使うデータを読み込みましょう。次のコードでは、引数parse_dates
を指定して、列日付
を日付時刻型として読み込んでいます。
読み込んだデータには、ある架空の店舗の来店者数が日単位で格納されています。In [1]:
import pandas as pd # 来店者数データを読み込み df = pd.read_csv("dataset/visitors.csv", index_col="日付", parse_dates=["日付"]) # 先頭5行を確認 df.head()
来店者数 | |
---|---|
日付 | |
2020-01-01 | 158 |
2020-01-02 | 98 |
2020-01-03 | 116 |
2020-01-04 | 144 |
2020-01-05 | 91 |
resample()
と集約メソッドを組み合わせると、指定した時間単位でデータを集約します。 たとえば”Y”(年)を指定し、sum()
と組み合わせると、年ごとの合計を計算します。
# 年ごとに合計する sum_year_df = df.resample("Y").sum() sum_year_df
来店者数 | |
---|---|
日付 | |
2020-12-31 | 41321 |
2021-12-31 | 40455 |
指定する時間単位を変えることで、簡単に集計する単位を変更できます。たとえば、四半期ごとに集計したい場合は”Q”を指定します。
# 四半期ごとに合計する sum_q_df = df.resample("Q").sum() sum_q_df
来店者数 | |
---|---|
日付 | |
2020-03-31 | 10349 |
2020-06-30 | 10008 |
2020-09-30 | 10599 |
2020-12-31 | 10365 |
2021-03-31 | 9874 |
2021-06-30 | 9707 |
2021-09-30 | 10518 |
2021-12-31 | 10356 |
resample()
では、groupby()
同様の集約の機能が使えます。
たとえば、agg()
を使って複数の集約値を計算することも可能です。次のコードでは、年ごとの合計、最小値、最大値、平均値を一括で計算しています。
# 年ごとに合計、最大値、最小値、平均値を計算 agg_year_df = df.resample("Y").agg(["sum", "max", "min", "mean"]) agg_year_df
来店者数 | ||||
---|---|---|---|---|
sum | max | min | mean | |
日付 | ||||
2020-12-31 | 41321 | 175 | 62 | 112.898907 |
2021-12-31 | 40455 | 188 | 33 | 110.835616 |
コメント