我目前正在尝试计算几只股票的数据集的简单移动平均线。为了简化起见,我仅在两家公司(和4天的时间)内尝试了代码,但输出似乎存在问题。下面是我的代码。
for index, row in df3.iloc[4:].iterrows():
if df3.loc[index,'CompanyId'] == df3.loc[index-4,'CompanyId']:
df3['SMA4'] = df3.iloc[:,1].rolling(window=4).mean()
else:
df3['SMA4'] = 0
这是输出:Output
数据框按日期和公司ID排序。所以需要发生的是,当公司编号与代码中规定的不相等时,输出应该为零,因为我无法计算两个不同公司的移动平均值。相反,它在第7、8、9行输出了两家公司的移动平均线。
答案 0 :(得分:0)
使用groupby.rolling
df['SMA4']=df.groupby('CompanyId',sort=False).rolling(window=4).Price.mean().reset_index(drop='CompanyId')
print(df)
CompanyId Price SMA4
0 1 75 NaN
1 1 74 NaN
2 1 77 NaN
3 1 78 76.00
4 1 80 77.25
5 1 79 78.50
6 1 80 79.25
7 0 10 NaN
8 0 9 NaN
9 0 12 NaN
10 0 11 10.50
11 0 11 10.75
12 0 8 10.50
13 0 9 9.75
14 0 8 9.00
15 0 8 8.25
16 0 11 9.00
答案 1 :(得分:0)
虽然ansev是正确的,因为手动循环要慢得多,所以应该使用特殊功能,但是我想说明为什么您的代码不起作用:
在if分支和else分支中,整个SMA4列都分配给(File.open
),并且由于在循环的最后一次运行中,if语句为true,因此else语句没有任何内容effect和SMA4永远不会为0。因此,要解决此问题,您可以先创建一个填充滚动平均值的列(请注意,这不在for循环中):
df3['SMA4']
然后运行循环以将无效行设置为0(尽管nan会更好。假设ansev答案中的数字正确,我会保留其他错误):
df3['SMA4'] = df3.iloc[:,1].rolling(window=4).mean()
输出(可能仍然是越野车):
for index, row in df3.iloc[4:].iterrows():
if df3.loc[index,'CompanyId'] != df3.loc[index-4,'CompanyId']:
df3.loc[index,'SMA4'] = 0