如何用函数与Lambda实现DataFrame列前3值均值与后续值比较并排错
问题解决与需求实现
原代码报错原因
原代码核心错误是对apply的使用逻辑完全误解:
df['Close'].apply(func)会把Close列的单个数值逐个传入func,而非整个DataFrame,因此func里的参数实际是float类型,自然没有columns属性,触发AttributeError。- 额外逻辑错误:循环遍历列名、固定取第4个值、直接返回终止函数等,完全不符合需求逻辑。
需求实现(两种方式)
需求明确:对Close列,从第4行(索引≥3,0开始计数)起,每个值与它前3个值的均值比较,大于则标记1,否则0;前3行因无足够前置数据,标记为0(可按需改为NaN)。
先构造测试数据:
import pandas as pd import numpy as np # 测试用DataFrame df = pd.DataFrame({'Close': [10, 20, 30, 25, 35, 15, 40]})
方式1:自定义函数(高效滚动窗口实现)
利用Pandas滚动窗口计算均值,性能远高于逐行遍历:
def mark_sentiment(df, col='Close'): # 计算前3个值的均值:窗口3的滚动均值后移1位,对应当前行的前3个值 prev3_mean = df[col].rolling(window=3).mean().shift(1) # 比较赋值:大于均值为1,否则为0 df['Sentiment'] = np.where(df[col] > prev3_mean, 1, 0) # 前3行无足够前置数据,标记为0 df.loc[:2, 'Sentiment'] = 0 return df # 调用函数生成结果 df = mark_sentiment(df)
方式2:Lambda+逐行Apply实现
适合理解逻辑,性能略低于滚动窗口(数据量大时不推荐):
# 重置索引确保连续(若原索引不连续需先执行) df = df.reset_index(drop=True) # Lambda表达式按行处理 df['Sentiment'] = df.apply( lambda row: 1 if row['Close'] > df['Close'].iloc[row.name-3:row.name].mean() else 0 if row.name >= 3 else 0, axis=1 )
结果示例
处理后df内容:
| Close | Sentiment |
|---|---|
| 10 | 0 |
| 20 | 0 |
| 30 | 0 |
| 25 | 1 |
| 35 | 1 |
| 15 | 0 |
| 40 | 1 |
内容的提问来源于stack exchange,提问作者Raagib khan
相关产品推荐
相关产品推荐

