Python函数中使用pandas iterrows()报错及加权计算需求咨询
解决方案:解决iterrows报错+实现分组滑动加权求和
先解决AttributeError: 'Series' object has no attribute 'iterrows'报错
你这个报错是因为分组后传给lambda的是Series对象,不是DataFrame。比如如果代码是df.groupby(['cust_id','order_id'])['Value'].apply(lambda g: ...),这里的g是单列的Series,自然没有iterrows方法。
要修复的话,要么:
- 去掉分组后的列指定,直接用
df.groupby(['cust_id','order_id']).apply(lambda g: ...),这样g就是每个分组的完整DataFrame,能调用iterrows; - 但更推荐直接抛弃
iterrows,用下面的高效方法实现需求——逐行遍历效率太低,数据量大的时候根本跑不动。
实现分组计算过去11个月加权乘积和
假设你的DataFrame包含cust_id、order_id、month(月份,比如YYYY-MM格式或整数序号)、Value、month_weight列,按以下步骤来:
1. 补全分组内的缺失月份
先把每个cust_id+order_id组合下的所有月份补全,缺失月份的Value和month_weight按0填充:
import pandas as pd # 获取所有唯一月份并排序 all_months = df['month'].unique() all_months.sort() # 生成每个分组的完整月份组合 group_keys = df[['cust_id', 'order_id']].drop_duplicates() full_groups = group_keys.merge(pd.DataFrame({'month': all_months}), how='cross') # 合并原始数据,补全缺失值 full_df = full_groups.merge(df, on=['cust_id', 'order_id', 'month'], how='left') full_df['Value'] = full_df['Value'].fillna(0) full_df['month_weight'] = full_df['month_weight'].fillna(0) # 按分组和月份排序,确保窗口计算顺序正确 full_df = full_df.sort_values(['cust_id', 'order_id', 'month']).reset_index(drop=True)
2. 计算滑动12个月的加权乘积和
用rolling窗口结合向量运算,计算每个窗口内Value * month_weight的总和:
def calculate_weighted_sum(window): return (window['Value'] * window['month_weight']).sum() # 按分组应用滑动窗口计算 full_df['rolling_weighted_sum'] = full_df.groupby(['cust_id', 'order_id']).apply( lambda g: g.rolling(window=12, closed='right').apply(calculate_weighted_sum, raw=False) ).reset_index(level=[0,1], drop=True)
关键说明
rolling(window=12)表示取当前行及前11行的12条数据,closed='right'确保包含当前行;- 全程用向量运算代替逐行遍历,效率比
iterrows高几个数量级,数据量大的时候差异特别明显; - 如果你的月份格式不是整数,比如是
datetime类型,先转成可排序的格式(比如df['month'] = pd.to_datetime(df['month']).dt.to_period('M'))再处理。
内容的提问来源于stack exchange,提问作者s nandan
相关产品推荐
相关产品推荐

