如何在Pandas DataFrame中按组统计时间t前的唯一x观测数
解决Pandas分组统计每行时间前不同x的数量问题
我来帮你搞定这个需求!咱们一步步来实现:针对每个分组Group,统计每行时间t之前变量x的不同观测值数量,同时忽略缺失的时间值,还要处理同组同x同日期重复的情况。
步骤1:数据预处理
首先,我们需要清理数据里的缺失时间(NaT),并且去掉同组同x同日期的重复行——因为这些重复行不会影响统计结果,反而会增加计算量。
步骤2:分组计算累积唯一值
接下来,对每个分组按时间排序,计算到当前时间点之前的不同x数量。这里要注意:同一时间点的多个x不能互相计入“之前”的统计里。
完整代码示例
先构造你的示例数据:
import pandas as pd # 构造示例数据 data = { 'Group': [1, 1, 1, 1, 2], 'x': ['a', 'b', 'b', 'c', 'a'], 't': ['2013-11-01', '2015-04-03', '2015-04-03', pd.NaT, '2017-03-01'] } df = pd.DataFrame(data) df['t'] = pd.to_datetime(df['t'])
然后执行核心逻辑:
# 1. 清理缺失时间的行 df_clean = df.dropna(subset=['t']) # 2. 去重:保留每个(Group, x, t)的唯一行 df_unique = df_clean.drop_duplicates(subset=['Group', 'x', 't']) # 3. 按分组和时间排序 df_unique = df_unique.sort_values(['Group', 't']) # 4. 计算每个分组内的累积唯一x数量(包含当前行) df_unique['cum_total'] = df_unique.groupby('Group')['x'].transform( lambda col: (~col.duplicated()).cumsum() ) # 5. 转换为「当前时间之前」的数量(减去当前行的x) df_unique['prev_unique_x'] = df_unique['cum_total'] - 1 # 6. 合并回原始DataFrame,保留所有行 df_result = df.merge( df_unique[['Group', 'x', 't', 'prev_unique_x']], on=['Group', 'x', 't'], how='left' ) # 7. 对原数据中t为NaT的行,设置结果为缺失值 df_result['prev_unique_x'] = df_result['prev_unique_x'].where( pd.notna(df_result['t']), pd.NA )
结果展示
运行后得到的df_result如下:
| Group | x | t | prev_unique_x |
|---|---|---|---|
| 1 | a | 2013-11-01 | 0 |
| 1 | b | 2015-04-03 | 1 |
| 1 | b | 2015-04-03 | 1 |
| 1 | c | NaT | |
| 2 | a | 2017-03-01 | 0 |
关键细节说明
- 去重处理:同组同
x同日期的重复行,统计结果一致,所以先去重提升效率。 - 时间排序:必须按分组和时间排序,才能保证累积统计的顺序正确。
- 同一时间点处理:用
~col.duplicated()标记首次出现的x,再用cumsum累积计数,确保同一时间点的多个x不会互相计入“之前”的数量。
内容的提问来源于stack exchange,提问作者Jan N.
相关产品推荐
相关产品推荐

