我目前正在尝试计算几只股票的数据集上的简单移动平均值。为了简单起见,我只在两家公司(和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排序。因此,需要发生的是,当公司id不等于代码中所述时,输出应该为零,因为我无法计算两个不同公司的移动平均值。相反,它输出两个公司的移动平均值,如第7,8,9行。
发布于 2019-11-10 01:31:01
使用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发布于 2019-11-10 02:27:08
虽然ansev认为您应该使用专用函数是正确的,因为手动循环要慢得多,但我想说明代码不能工作的原因:在if分支和else分支中,整个SMA4列都被分配给(df3['SMA4']),而且因为在最后一次运行循环时,if语句是真的,所以else语句没有任何作用,SMA4永远不会为0。因此,要解决这个问题,您可以首先创建用滚动平均值填充的列(请注意,这不在for循环中):
df3['SMA4'] = df3.iloc[:,1].rolling(window=4).mean()然后运行循环,将无效行数设置为0(尽管nan会更好。我保留了其他bug,假设ansev答案中的数字是正确的):
for index, row in df3.iloc[4:].iterrows():
if df3.loc[index,'CompanyId'] != df3.loc[index-4,'CompanyId']:
df3.loc[index,'SMA4'] = 0 输出(可能仍有错误):
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 2 10 0.00
8 2 9 0.00
9 2 12 0.00
10 2 11 0.00
11 2 11 10.75
12 2 8 10.50
13 2 9 9.75
14 2 8 9.00
15 2 8 8.25
16 2 11 9.00https://stackoverflow.com/questions/58781762
复制相似问题