为什么pd.rolling和.apply()从返回单个值的函数返回多个输出?

2024-10-02 08:30:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个滚动函数:

  1. 在每个df中用3列划分两个数据帧
  2. 根据步骤1中的输出计算每行的平均值
  3. 对步骤2的平均值求和

这可以通过使用pd.iterrows()来完成,因此可以在每一行中循环。但是,在处理较大的数据集时,这将是低效的。因此,我的目标是创建一个pd.rolling函数,它可以更快地完成这项工作

我需要帮助的是理解为什么我下面的方法返回多个值,而我使用的函数只返回一个值

编辑:我已经用生成所需输出的代码更新了问题

这是我正在使用的测试数据集:

#import libraries
import pandas as pd
import numpy as np 

#create two dataframes
values = {'column1': [7,2,3,1,3,2,5,3,2,4,6,8,1,3,7,3,7,2,6,3,8],
        'column2': [1,5,2,4,1,5,5,3,1,5,3,5,8,1,6,4,2,3,9,1,4],
        "column3" : [3,6,3,9,7,1,2,3,7,5,4,1,4,2,9,6,5,1,4,1,3]
        }

df1 = pd.DataFrame(values)
df2 = pd.DataFrame([[2,3,4],[3,4,1],[3,6,1]])
print(df1)
print(df2)

    column1  column2  column3
0         7        1        3
1         2        5        6
2         3        2        3
3         1        4        9
4         3        1        7
5         2        5        1
6         5        5        2
7         3        3        3
8         2        1        7
9         4        5        5
10        6        3        4
11        8        5        1
12        1        8        4
13        3        1        2
14        7        6        9
15        3        4        6
16        7        2        5
17        2        3        1
18        6        9        4
19        3        1        1
20        8        4        3
   0  1  2
0  2  3  4
1  3  4  1
2  3  6  1

通过循环每行来实现所需输出的一种方法:

RunningSum = []
for index, rows in df1.iterrows():
    if index > 3:
        Div = abs((((df2 / df1.iloc[index-3+1:index+1].reset_index(drop="True").values)-1)*100))
        Average = Div.mean(axis=0)
        SumOfAverages = np.sum(Average)
        RunningSum.append(SumOfAverages)
        
        
            
        #printing my desired output values
        print(RunningSum)
[330.42328042328046,
 212.0899470899471,
 152.06349206349208,
 205.55555555555554,
 311.9047619047619,
 209.1269841269841,
 197.61904761904765,
 116.94444444444444,
 149.72222222222223,
 430.0,
 219.51058201058203,
 215.34391534391537,
 199.15343915343914,
 159.6031746031746,
 127.6984126984127,
 326.85185185185185,
 204.16666666666669]

但是,在处理大型数据集时,这将是及时的。因此,我尝试创建一个应用于pd.rolling()对象的函数

def SumOfAverageFunction(vals):
    Div = df2 / vals.reset_index(drop="True")
    Average = Div.mean(axis=0)
    SumOfAverages = np.sum(Average)
    return SumOfAverages

RunningSum = df1.rolling(window=3,axis=0).apply(SumOfAverageFunction)

这里的问题是,我的函数返回多个输出。我怎样才能解决这个问题

print(RunningSum)
     column1   column2   column3
0        NaN       NaN       NaN
1        NaN       NaN       NaN
2   3.214286  4.533333  2.277778
3   4.777778  3.200000  2.111111
4   5.888889  4.416667  1.656085
5   5.111111  5.400000  2.915344
6   3.455556  3.933333  5.714286
7   2.866667  2.066667  5.500000
8   2.977778  3.977778  3.063492
9   3.555556  5.622222  1.907937
10  2.750000  4.200000  1.747619
11  1.638889  2.377778  3.616667
12  2.986111  2.005556  5.500000
13  5.333333  3.075000  4.750000
14  4.396825  5.000000  3.055556
15  2.174603  3.888889  2.148148
16  2.111111  2.527778  1.418519
17  2.507937  3.500000  3.311111
18  2.880952  3.000000  5.366667
19  2.722222  3.370370  5.750000
20  2.138889  5.129630  5.666667

Tags: 数据函数importdivindexnanpddf1
1条回答
网友
1楼 · 发布于 2024-10-02 08:30:43

重新排序操作后,可以简化计算

BASE = df2.sum(axis=0) /3
BASE_series = pd.Series({k: v for k, v in zip(df1.columns, BASE)})
result = df1.rdiv(BASE_series, axis=1).sum(axis=1)

print(np.around(result[4:], 3))

产出:

4     5.508
5     4.200
6     2.400
7     3.000
...

如果您不想在索引4之前计算任何内容,请更改:

df1.iloc[4:].rdiv(...

相关问题 更多 >

    热门问题