Python 环路简单移动平均的计算

Python 环路简单移动平均的计算,python,pandas,dataframe,output,moving-average,Python,Pandas,Dataframe,Output,Moving Average,我目前正在尝试计算几个股票数据集的简单移动平均数。为了简单起见,我只在两家公司(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() el

我目前正在尝试计算几个股票数据集的简单移动平均数。为了简单起见,我只在两家公司(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
以下是输出:


数据帧是按日期和公司id排序的。因此需要做的是,当公司id不等于代码中所述的值时,输出应该为零,因为我无法计算两个不同公司的移动平均值。取而代之的是,它对两家公司的移动平均值,如第7、8、9行

使用
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

虽然ansev认为您应该使用专用函数是正确的,因为手动循环要慢得多,但我想说明为什么您的代码不起作用: 在if分支和else分支中,整个SMA4列都被分配到(
df3['SMA4']
),因为在循环的最后一次运行中,if语句为true,因此else语句没有任何效果,SMA4永远不会为0。为了解决这个问题,您可以首先创建填充了滚动平均值的列(注意,这不是for循环):

然后运行循环将无效行设置为0(尽管nan会更好。我保留了其他错误,假设ansev的答案中的数字是正确的):

输出(可能仍然有bug):

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 
    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.00