Python Pandas-基于多个列的条件的3D数据框累积,直到达到值

时间:2019-03-18 14:43:21

标签: python pandas cumsum

我在获取python 3D数据帧的累积总和时遇到了一些困难。

我创建的示例数据框是:

import numpy as np
import pandas as pd

arr=np.array([[[23, 10],
        [ 24,  5],
        [ 28,  8],
        [ 30, 11],
        [ 31, 1]],

       [[20, 11],
        [21, 3],
        [22, 5],
        [29, 15],
        [30, 10]],

       [[22, 26],
        [23, 29],
        [25, 32],
        [33, 10],
        [34, 15]]])

names = ['x', 'y', 'z']
index = pd.MultiIndex.from_product([range(s)for s in arr.shape], names=names)
df = pd.DataFrame({'Day': arr.flatten()}, index=index)['Day']
df = df.unstack(level='z')
df.columns = ['Price', 'Qty']
df.index.names = ['DATE', 'i']

在指定的日期范围内,如果价格比某个值(x)便宜,我想查找商品数量的总和。但是,当总和超过某个特定数字(y)时,我将停下来,无论其他商店中是否还有任何符合该最低要求的日期。价格标准。我将从最早的日期开始进行总结,并在每个日期从最低的价格开始进行总结。然后,我会找到直到停止点为止的加权平均价格。

在上述数据框中,说我的标准是(1)日期0和1,(2)价格等于或低于25,(3)当数量总和首次超过20时停止。在这种情况下,相关数据是日期0中的价格23和24,以及日期1中的价格20。这是因为日期0中的价格23和24的数量之和是15,因此小于20,但日期1中价格20的数量相加,累计变为26,因此该过程停止。因此,加权平均值为(23 * 10)+(24 * 5)+(20 * 5)/ 20

我当前的方法太麻烦了,因为使用while循环来遍历时间轴,并为每个日期使用另一个while循环,这样如果价格比我的标准便宜,我将在数量和价格加权数量上加上跟踪总和。当跟踪总和大于指定的值时,我将停止该过程并计算加权平均值。然后,我还可以返回过程停止的位置。

是否希望以更有效的方式获得建议?

1 个答案:

答案 0 :(得分:0)

这是一个执行此操作的自定义函数,只需像示例中那样插入变量即可。

def weighted_average(df, dates, price_limit, stop_sum):
    # filter multiindex for your dates, plus price_limits
    tmp = df.loc[dates].loc[df['Price'] <= price_limit]
    # find index of halting cumsum condition, take tmp until there
    tmp = tmp.loc[:(tmp['Qty'].cumsum() > stop_sum).idxmax()]
    # update last value
    tmp.iat[-1, df.columns.get_loc('Qty')] -= tmp['Qty']sum() - stop_sum
    # return the weighted average
    return tmp.product(axis=1).sum() / stop_sum

dates = [0, 1]
price_limit = 25
stop_sum = 20

weighted_average(df, dates, price_limit, stop_sum)
> 22.5

对于过滤器(tmp = df.loc[dates].loc[df['Price'] <= price_limit]),替代方法(对于大型数据集,性能可能更高)

tmp = df[(df.index.get_level_values(0).isin(dates)) & (df['Price'] <= price_limit)]