顧客コード2行を1行に集約(groupby)

投稿者: | 2022-11-01

# サンプルDF
l = [
    ['1', '20', '202210', '20220910', '20220930', '5'],
    ['1', '30', '202210', '20221001', '20221009', '3'],
    ['2', '50', '202210', '20220920', '20220930', '2'],
    ['2', '40', '202210', '20221001', '20221019', '4'],
    ['3', '20', '202210', '20220925', '20221024', '5'],
    ['4', '40', '202210', '20220912', '20221011', '4'],
    ['4', '20', '202211', '20221012', '20221013', '5'],
    ]

col = ['顧客コード', '使用量', '対象月', 'from', 'to', '単価']
import pandas as pd

df = pd.DataFrame(l)
df.columns = col
df = df.astype({'顧客コード': object, '使用量':int, '対象月':int, 'from':int, 'to':int, '単価':int})
df = df.sort_values(by=['顧客コード', 'from'], ascending=[True, True]) 
df
# 顧客コード別に複数行を集約する(表記上、単価は平均値になっている)
def agg_df(df):
    new_df =  df.groupby('顧客コード').agg(
        {'使用量':'sum', '対象月':'mean', 'from':'min', 'to':'max', '単価':'mean'}).\
        reset_index()
    return new_df
# 異なる対象月が1つに集約されないよう、対象月別に集計後にマージする
def merge_by_month(df):
    l = []
    for month in df['対象月'].unique().tolist():
        # print(month)
        df_by_month = df.query('対象月 == @month')
        agg_df_by_month = agg_df(df_by_month)
        l.append(agg_df_by_month)
    merge_df = pd.concat(l).sort_values(by=['顧客コード', '対象月', 'from']).reset_index(drop=True)
    return merge_df
merge_by_month(df)