如何获取多个列之间的滚动比例?

1 投票
2 回答
44 浏览
提问于 2025-04-13 20:38

我想要对每一行的数据计算一个占总值(销售额)的比例。举个例子,对于某一行,我们会取前面两列的两个值的总和,然后计算每一列的比例。

假设我们有以下的数据集:

import pandas as pd

df = pd.DataFrame({
    'factory1sales': [0, 1, 2, 3, 4], 
    'factory2sales': [5, 6, 7, 8, 9]
})
   factory1sales  factory2sales  rolling_proportion_factory1  rolling_proportion_factory1
0              0              5      
1              1              6      
2              2              7      
3              3              8      
4              4              9  0.25                         0.75

对于factory1,销售额的滚动比例(窗口大小为2)将会是:

(2 + 3) / ((2 + 3) + (7 + 8)) = 0.25

我该怎么做呢?我知道这可能需要结合使用pd.shiftpd.rolling等功能。

2 个回答

2

我会使用 rollingeval,然后从 rolling_proportion_factory1 计算出 rolling_proportion_factory2,因为这两个的总和都是1:

df['rolling_proportion_factory1'] = (df.rolling(2, closed='left').sum()
                                       .eval('factory1sales/(factory1sales+factory2sales)')
                                    )
df['rolling_proportion_factory2'] = 1-df['rolling_proportion_factory1']

输出结果:

   factory1sales  factory2sales  rolling_proportion_factory1  rolling_proportion_factory2
0              0              5                          NaN                          NaN
1              1              6                          NaN                          NaN
2              2              7                     0.083333                     0.916667
3              3              8                     0.187500                     0.812500
4              4              9                     0.250000                     0.750000
2

我也成功地用连锁的 shiftrollingsum 等方法让它工作起来。理想情况下,这些代码可以简化一下,让人更容易理解。

for column in columns:
    sum_one_factory = df.shift(1).rolling(2)[column].sum().values.ravel()
    sum_all_factories = df.shift(1).rolling(2)[columns].sum().sum(axis=1)

    df[f'rolling_proportion_{column}'] = sum_one_factory / sum_all_factories
rolling_proportion_factory1sales  rolling_proportion_factory2sales
NaN                               NaN
NaN                               NaN
0.083333                          0.916667
0.187500                          0.812500
0.250000                          0.750000

撰写回答