如何按组删除DataFrame首次出现'H'后的行并统计前置活动?
解决Pandas分组统计'H'首次出现前活动数量的问题
一、实现你的思路(步骤2代码)
你的思路逻辑清晰,以下是完整流程的代码实现,重点补充步骤2的实现:
- 按Key和Date排序(确保日期顺序正确,即使原数据已排序也建议保留,避免异常情况)
import pandas as pd df = pd.DataFrame({'Key':[1,1,1,1,2,2,2,4,4,4,5,5], 'Activity':['A','A','H','B','B','H','H','A','C','H','H','B'], 'Date':['2022-12-03','2022-12-04','2022-12-06','2022-12-08','2022-12-03','2022-12-06','2022-12-10','2022-12-03','2022-12-04','2022-12-07','2022-12-03','2022-12-13']}) # 按Key分组、Date升序排序 df = df.sort_values(['Key', 'Date'])
- 按组删除'H'首次出现后的所有行
通过标记组内'H'的累计出现次数,筛选出首次出现前的行:
# 标记每行是否为'H' df['is_H'] = df['Activity'] == 'H' # 按组计算'H'的累计出现次数,首次出现后累计值会保持为1及以上 df['cum_H'] = df.groupby('Key')['is_H'].cumsum() # 筛选累计次数为0的行(即'H'首次出现前的所有行) df_filtered = df[df['cum_H'] == 0].drop(['is_H', 'cum_H'], axis=1)
- 按['Key','Activity']分组统计数量
count_result = df_filtered.groupby(['Key', 'Activity']).size().reset_index(name='Count') print(count_result)
输出结果:
Key Activity Count 0 1 A 2 1 2 B 1 2 4 A 1 3 4 C 1
二、更优方案(向量化操作,效率更高)
避免创建中间列,直接用transform实现向量化筛选,适合大数据量场景:
# 1. 确保排序 df_sorted = df.sort_values(['Key', 'Date']) # 2. 标记每个组内当前行是否在'H'首次出现之前 before_first_H = df_sorted.groupby('Key')['Activity'].transform( lambda x: x.eq('H').cumsum() == 0 ) # 3. 筛选后统计数量 optimal_result = df_sorted[before_first_H].groupby(['Key', 'Activity']).size().reset_index(name='Count') print(optimal_result)
这个方案用transform替代了中间列的创建,逻辑更紧凑,执行效率更高,结果和上述方法完全一致。
补充说明
- 对于组内第一个活动就是'H'的情况(如示例中的Key=5),因为'H'首次出现前没有活动,所以不会出现在统计结果中;如果需要显示这类Key的0值,可以追加
unstack(fill_value=0).stack()处理。 - 排序步骤必须保留,否则无法保证找到的是首次出现的'H'。
内容的提问来源于stack exchange,提问作者deega
相关产品推荐
相关产品推荐

