今回は会社の実務で利用した、Pythonのpandasによる分析手法を紹介する。

実務ではECサイトのマーケティングを行っているのだが、今回は1ヶ月の日にち(1〜31日まで)を5日ごと6つの階級に分け、どの日付範囲が最も売上が高いのかを分析してみた。

サンプルデータフレームの用意

まずは分析の対象となるデータセットを用意する。

本来であれば、実務で利用しているシステムのデータベースやCSVからデータを読み込むのだが、今回はサンプルとして以下のデータフレームを用意した。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.normal(100000, 20000, 1000),
                 index=pd.date_range('2017/01/01', periods=1000),
                 columns=['uriage'])

一応解説しておくと、4行目のrandom.normal関数は、第一引数に平均値、第二引数に標準偏差、第三引数に生成する配列の要素数を指定し、引数に与えた値に基づいた正規分布した乱数を生成する。

今回はindexに2017年1月から1000日間の日付範囲を指定し、1000日間の売上データを生成してみた。

さらにこのデータフレームに対し、「日」の値を格納した列を追加し、小数となっている売上データを整数に型変換してみた。

# 列dayに「日」を追加
df['day'] = df.index.day

# 列numを小数から整数に変換
df['uriage'] = df['uriage'].astype(int)

ここまでの処理を終えたデータフレームを確認すると以下のようになる。

            uriage  day
2017-01-01   77241    1
2017-01-02  122879    2
2017-01-03  131097    3
...
2019-09-25   91474   25
2019-09-26   78731   26
2019-09-27  105774   27

[1000 rows x 2 columns]

cut関数でビン分割

pandasのcut関数で、データフレームをビン分割することができる。

第一引数に対象のデータフレームを、第二引数に分割ルールを指定する。

今回は日が31と割り切れない値なので、リストに境界となる値を指定する方式を採った。
※この他、指定した整数で等間隔に分割する方法などもある。

pd.cut(df['day'], [0, 5, 10, 15, 20, 25, 31])
# 2017-01-01      (0, 5]
# 2017-01-02      (0, 5]
# 2017-01-03      (0, 5]
# 2017-01-04      (0, 5]
# 2017-01-05      (0, 5]
# 2017-01-06     (5, 10]
# 2017-01-07     (5, 10]
# 2017-01-08     (5, 10]
# 2017-01-09     (5, 10]
# 2017-01-10     (5, 10]
# 2017-01-11    (10, 15]
# 2017-01-12    (10, 15]
# 2017-01-13    (10, 15]
# 2017-01-14    (10, 15]
# 2017-01-15    (10, 15]
...

分割したビンごとにグルーピングして平均を算出する

これで各行に階級を設定することができたので、今度はこれを応用して階級ごとのグルーピングをおこなう。

groupby関数でグルーピングし、meanでグループごとの平均値を算出する。

df_rng_5day = df.groupby(pd.cut(df['day'], [0, 5, 10, 15, 20, 25, 31])).mean()

結果は次のとおりとなる。

df_rng_5day['uriage']
# day
# (0, 5]      101388.733333
# (5, 10]     101457.206061
# (10, 15]    100264.648485
# (15, 20]    101313.951515
# (20, 25]    102257.654545
# (25, 31]     99083.628571
# Name: uriage, dtype: float64

うまく日付範囲ごとの売上平均値が取得できた。

ちなみに実際の業務ではこの分析手法により、月初、月末が最も売れ行きが良いことが分かった。
そしてこの結果を、広告予算の配分を決める判断材料として使うことができた。