在Pandas数据框中基于有效值计算每行前3个有效值滚动均值
解决方案:计算基于前3个有效值的滚动均值
针对你给出的稀疏Pandas数据框,我们可以通过以下步骤实现每行基于之前所有非NaN有效值中最近3个的滚动均值计算:
import pandas as pd import numpy as np # 先构造你提供的数据框(方便直接测试) data = { 'a001': [1.0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 4.0, np.nan, np.nan, np.nan, np.nan], 'a002': [np.nan, np.nan, np.nan, 3.0, np.nan, np.nan, 6.0, np.nan, np.nan, np.nan, np.nan, np.nan], 'a003': [np.nan, np.nan, 2.0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], 'a004': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 1.0, np.nan, np.nan, np.nan], 'a005': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 5.0] } time_axis = pd.to_datetime(['2017-02-07', '2017-02-14', '2017-03-20', '2017-04-03', '2017-05-15', '2017-06-05', '2017-07-10', '2017-07-17', '2017-07-24', '2017-08-07', '2017-08-14', '2017-08-28']) df = pd.DataFrame(data, index=time_axis) # 步骤1:提取所有非NaN有效值,整理为带时间戳的长格式 valid_records = df.stack().reset_index(name='value') valid_records.columns = ['time', 'column', 'value'] valid_records = valid_records.sort_values('time').reset_index(drop=True) # 步骤2:定义函数,计算单个时间点对应的前3个有效值均值 def get_rolling_mean(current_time): # 筛选当前时间及之前的所有有效值 prior_vals = valid_records[valid_records['time'] <= current_time]['value'] # 取最近的3个值 last_three = prior_vals.tail(3) # 无有效值返回NaN,不足3个则用现有值计算均值(可按需修改规则) return last_three.mean() if not last_three.empty else np.nan # 步骤3:将计算结果映射回原数据框 df['rolling_mean_prev3'] = df.index.map(get_rolling_mean) # 查看最终结果 print(df)
关键步骤解释
- 提取有效值:用
stack()把宽格式数据转成长格式,自动过滤NaN,得到所有出现过的有效数据及其时间戳,方便后续追踪历史数据。 - 排序与筛选:先按时间排序有效值,确保我们取到的是严格按时间顺序的历史数据;对每个时间点,筛选出它之前的所有有效值,再取最近3个。
- 灵活适配规则:如果需要不足3个有效值时返回NaN,只需把函数里的判断改成
return last_three.mean() if len(last_three) >=3 else np.nan。
最终结果示例
a001 a002 a003 a004 a005 rolling_mean_prev3 2017-02-07 1.0 NaN NaN NaN NaN NaN 2017-02-14 NaN NaN NaN NaN NaN 1.000000 2017-03-20 NaN NaN 2.0 NaN NaN 1.000000 2017-04-03 NaN 3.0 NaN NaN NaN 1.500000 2017-05-15 NaN NaN NaN NaN NaN 2.000000 2017-06-05 NaN NaN NaN NaN NaN 2.000000 2017-07-10 NaN 6.0 NaN NaN NaN 2.000000 2017-07-17 4.0 NaN NaN NaN NaN 3.666667 2017-07-24 NaN NaN NaN 1.0 NaN 4.333333 2017-08-07 NaN NaN NaN NaN NaN 3.666667 2017-08-14 NaN NaN NaN NaN NaN 3.666667 2017-08-28 NaN NaN NaN NaN 5.0 3.666667
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

