添加列基于GROUPBY

问题描述 投票:0回答:1

达到一定的分析结束时,我有(在示例df_delta)的单个数据帧包含ID,组,基线,始发,subsequent_events,和delta_month。

我的方法:合并,加入或基于ID的后续事件(df_a_b),然后总和(在片段所示CONCAT)串联。

import pandas as pd
data_a = {
'id': [3, 2, 1, 0]
,'group':['test','test','control','control']
,'original_event_date': ['2018-01-02', '2018-02-01', '2018-03-20', '2018-01-01']
,'baseline':['100', '20', '1000', '5']
}
df_a = pd.DataFrame.from_dict(data_a)

data_b = {
'id': [3,3,3,3, 1, 0,0]
,'subsequent_event_date': ['2018-02-02','2018-03-02','2018-04-02', '2018-01-15','2018-03-13', '2018-03-20', '2018-04-01']
,'subsequent_events':['3','5','7','2','20', '10', '5']
}
df_b = pd.DataFrame.from_dict(data_b)

#assign original event month to each record [id]
df_a['origination'] = pd.to_datetime(df_a['original_event_date']).dt.strftime('%Y-%m')

#sum subsequent events by record [id]                
df_sum_b = df_b.groupby(by=("id"))["subsequent_events"].sum()

#join the two to get delta_month
df_a_b = pd.concat([df_a, df_b], axis=1, sort=False) 

df_delta = pd.merge(df_a,df_b,how='left',on='id')
df_delta['delta_month'] = (pd.to_datetime(df_delta['subsequent_event_date']).dt.year - pd.to_datetime(df_delta['original_event_date']).dt.year) * 12 \
                    + (pd.to_datetime(df_delta['subsequent_event_date']).dt.month - pd.to_datetime(df_delta['original_event_date']).dt.month)

df_delta = df_delta.drop(columns=['original_event_date','subsequent_event_date']).fillna(0)

一个理想的输出将包括:测试/对照,原始事件的YYYY-MM,delta_month作为基团和基线总和的每个delta_month的百分比。

加入,合并,似乎CONCAT不具备此功能。如果每个原始事件与随后的事件相关联,如果没有后续事件发生的原始事件值都将丢失,如果双方随后发生的事件和原始事件相同的动作相加会有原始事件的对应delta_month多

有没有人对如何处理这个区别什么更好的建议?

python pandas pandas-groupby
1个回答
0
投票

我会尽可能多的加入到未分组帧地(个人喜好),所以使用transform是很好的。

在没有后续事件发生的原始事件值将丢失

这可以通过fillna解决。因为它看起来像你想通过数字来总结subsequent_events,我们不妨投从一开始就整数(或浮筒或......)。

df_delta['subsequent_events'] = df_delta['subsequent_events'].fillna('0').astype(int)
df_delta['sum_events_in_month'] = df_delta.groupby(['group','origination','delta_month'])['subsequent_events'].transform('sum').fillna(0)
df_delta['delta_month'].fillna(0, inplace=True)
df_sum_b = df_delta.groupby(['group','origination','delta_month'])[['baseline', 'sum_events_in_month']].apply(lambda x: x.astype(int).sum())

df_sum_b['pct'] = df_sum_b['sum_events_in_month']/df_sum_b['baseline']

(编辑:建议编辑并指出一个缺陷,但我不认为解决方案工作做,而不是.astype(int).fillna(0),因为缺失值不能是整数投打破,我已经换了为了.fillna('0').astype(int)%的。评论,我已经添加了一些更fillnas,似乎这样的伎俩。)

© www.soinside.com 2019 - 2024. All rights reserved.