データ分析の中で、特定の集計期間中「購入を行なっていない」顧客を調べることがあったので、これをpandasで調べる方法を紹介する。

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

以下のような二つのデータフレームがあるとする。

import pandas as pd

# 売上データ
df_uriage = pd.DataFrame([['2019-06-13', '0001', 3, '0001'],
                         ['2019-07-13', '0002', 5, '0002'],
                         ['2019-08-13', '0003', 4, '0001'],
                         ['2019-09-13', '0001', 1, '0003']],
                        columns=['売上日', '商品ID', '数量', '顧客ID'])

print(df_uriage)
#           売上日  商品ID  数量  顧客ID
# 0  2019-06-13  0001   3  0001
# 1  2019-07-13  0002   5  0002
# 2  2019-08-13  0003   4  0001
# 3  2019-09-13  0001   1  0003

# 顧客データ
df_customer = pd.DataFrame([['0001', '山田太郎', '大阪府'],
                           ['0002', '鈴木一郎', '東京都'],
                           ['0003', '佐藤あゆみ', '北海道'],
                           ['0002', '田中将太', '福岡県']],
                          columns=['顧客ID', '氏名', '都道府県'])
print(df_customer)
#    顧客ID     氏名 都道府県
# 0  0001   山田太郎  大阪府
# 1  0002   鈴木一郎  東京都
# 2  0003  佐藤あゆみ  北海道
# 3  0002   田中将太  福岡県

今回はわかりやすく各4行のデータを用意したので一目で分かるが、実際のシステムで「購入を行なっていない」顧客を調べるとなったらなかなか骨が折れるだろう。

二つのデータを結合し、rightジョインで調べる

二つのデータフレームをmerge関数で結合する。
ここでポイントとなるのが「how=’right’」。

rightジョインで結合することで、購入を行なっていない顧客の売上データの値が欠損値を表す「NaN」となる。

away_data = pd.merge(df_uriage, df_customer, left_on='顧客ID', right_on='顧客ID', how='right')
print(away_data)
#           売上日  商品ID   数量  顧客ID     氏名 都道府県
# 0  2019-06-13  0001  3.0  0001   山田太郎  大阪府
# 1  2019-08-13  0003  4.0  0001   山田太郎  大阪府
# 2  2019-07-13  0002  5.0  0002   鈴木一郎  東京都
# 3  2019-09-13  0001  1.0  0003  佐藤あゆみ  北海道
# 4         NaN   NaN  NaN  0004   田中将太  福岡県

購入を行なっていない顧客(欠損値が含まれている行)のみを抽出したい場合は、以下のようにisnull関数を使うと良い。

away_data[away_data['売上日'].isnull()]

#    売上日 商品ID  数量  顧客ID    氏名 都道府県
# 4  NaN  NaN NaN  0004  田中将太  福岡県

今回はpandasを使った例を紹介したが、通常のSQLでもrightジョインを使ってこのような集計を行うことができる。