分组DataFrame滚动均值自定义窗口:取4个唯一值计算
解决DataFrame分组滚动均值(仅纳入同组内4个唯一值)的问题
针对你的需求,我们需要先明确核心逻辑:同一Group内,仅当已经出现至少4个不同的唯一值时,计算最近4个唯一值的等权重均值,否则返回NaN;同时原DataFrame中每个唯一值会重复多次(你提到的3个重复为一组),所以每个唯一值对应的所有行都要应用同一个均值结果。
下面是具体的实现步骤和代码:
步骤拆解
- 分组提取唯一值序列:对每个Group,按数值出现的先后顺序提取唯一值,并记录每个唯一值对应的原DataFrame行索引。
- 计算唯一值的滚动均值:对每个Group的唯一值序列,计算窗口大小为4的滚动均值(仅当窗口内凑齐4个值时生效,不足则返回NaN)。
- 映射均值回原DataFrame:将每个唯一值对应的滚动均值,批量赋值给原DataFrame中该值所在的所有行。
代码实现
假设你的DataFrame名为df,列名分别为Group和Column to roll:
import pandas as pd # 示例DataFrame data = { 'Group': [1,2,2,2,2,2,2,2,2,2,2,2,2], 'Column to roll': [9,5,5,4,4,4,3,3,3,6,6,6,8] } df = pd.DataFrame(data) # 1. 对每个Group,整理唯一值顺序及对应行索引 grouped = df.groupby('Group')['Column to roll'] group_unique_info = {} for group, series in grouped: # 按出现顺序提取唯一值 unique_vals = series.unique() # 记录每个唯一值对应的所有行索引 val_to_indices = {val: series[series == val].index for val in unique_vals} group_unique_info[group] = {'unique_vals': unique_vals, 'val_to_indices': val_to_indices} # 2. 计算滚动均值并映射回原表 df['Output'] = pd.NA for group, info in group_unique_info.items(): unique_vals = info['unique_vals'] val_to_indices = info['val_to_indices'] # 计算窗口为4的滚动均值,min_periods=4确保只有凑齐4个值才计算 rolling_means = pd.Series(unique_vals).rolling(window=4, min_periods=4).mean() # 把均值赋值给对应行 for idx, mean_val in rolling_means.items(): if not pd.isna(mean_val): target_val = unique_vals[idx] df.loc[val_to_indices[target_val], 'Output'] = mean_val # 查看结果 print(df)
结果说明
运行代码后得到的Output列符合预期:
| Group | Column to roll | Output |
|---|---|---|
| 1 | 9 | NaN |
| 2 | 5 | NaN |
| 2 | 5 | NaN |
| 2 | 4 | NaN |
| 2 | 4 | NaN |
| 2 | 4 | NaN |
| 2 | 3 | NaN |
| 2 | 3 | NaN |
| 2 | 3 | NaN |
| 2 | 6 | 4.5 |
| 2 | 6 | 4.5 |
| 2 | 6 | 4.5 |
| 2 | 8 | 5.25 |
- Group1仅1个唯一值,无法凑齐4个,所以输出NaN;
- Group2前3个唯一值(5、4、3)对应的所有行都输出NaN;第4个唯一值6出现时,计算
(5+4+3+6)/4=4.5;第5个唯一值8出现时,计算(4+3+6+8)/4=5.25,对应行统一赋值该均值。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

