熊猫-将列的一部分聚合为新列中的新值

阿克塞尔

我有一个带有仓库数据的大pandas数据框,df其中显示了收到的物品数量。

将该结构的相关部分想象为:

Date         SKU    received
2017-05-29   sku1   0
2017-05-30   sku1   0
2017-05-31   sku1   0
2017-06-01   sku1   0
2017-06-02   sku1   6
2017-06-03   sku1   2
2017-05-29   sku2   4
2017-05-30   sku2   4
2017-05-31   sku2   0
2017-06-01   sku2   0
2017-06-02   sku2   0
2017-06-03   sku2   24

在这里,我想重新构建订单流程。我知道,星期一会检查库存水平,然后根据库存水平下达新订单。大约一周后,订单到达仓库,有时会分成多次装运。

我想为工作日(df["Weekday"])和下订单(df["Order"]创建一个额外的列根据工作日,我想汇总接下来4到11天(仅限于相关SKU)的“已接收”列的数据。

输出如下所示:

Date         SKU    received    Weekday    Order
2017-05-29   sku1   0           0          8
2017-05-30   sku1   0           1          0
2017-05-31   sku1   0           2          0  
2017-06-01   sku1   0           3          0
2017-06-02   sku1   6           4          0
2017-06-03   sku1   2           5          0
2017-05-29   sku2   4           0          24
2017-05-30   sku2   4           1          0
2017-05-31   sku2   0           2          0
2017-06-01   sku2   0           3          0
2017-06-02   sku2   0           4          0
2017-06-03   sku2   24          5          0

这是我尝试的代码:

import pandas as pd

# 0 is Monday, 1 is Tuesday, etc
df["Weekday"] = df["Date"].dt.dayofweek

# create new column for the orders
df["Order"] = 0

min_days = 4
max_days = min_days + 7

for i in range(len(df)):
    if df.loc[i, "Weekday"] == 0:
        df.loc[i, "Order"] = df.loc[(df.Date >= df.loc[i, "Date"] + pd.to_timedelta(min_days, unit="D")) &
                                    (df.Date < df.loc[i, "Date"] + pd.to_timedelta(max_days, unit="D")) &
                                    (df.SKU == df.loc[i, "SKU"]), "received"].sum()

它似乎可以完成工作,但是速度很慢。也许有人可以帮助我找到更多的pythonic / pandas方法来节省一些计算时间。

谢谢你的帮助。

松弛

这是使用pandas groupby和transform的可能解决方案。

第一个想法是,您可以通过计算总和的差额来实现两天之间的计数。另外,请注意[::-1]两次转换订单(的技巧,以便将来有一个连续的总和领料日。

def count_between(ts, min_days, max_days):
    return ts[::-1].pipe(lambda y: y.rolling(max_days,1).sum() - y.rolling(min_days-1,1).sum())[::-1]

此功能将为您提供每天的结果,因此您可以将结果限制为星期一,仅将所有其他条目设置为0(使用[.where][1])。

设置Date为索引后,您可以执行以下操作:

order = df.groupby('SKU')\
          .transform(lambda x: count_between(x, min_days, max_days)\
                               .where(lambda y: y.index.dayofweek==0, other = 0))
order.columns = ['Order']

这给出了预期的结果:

pd.concat([df, order], axis = 1)
Out[319]: 
             SKU  received  Order
Date                             
2017-05-29  sku1         0    8.0
2017-05-30  sku1         0    0.0
2017-05-31  sku1         0    0.0
2017-06-01  sku1         0    0.0
2017-06-02  sku1         6    0.0
2017-06-03  sku1         2    0.0
2017-05-29  sku2         4   24.0
2017-05-30  sku2         4    0.0
2017-05-31  sku2         0    0.0
2017-06-01  sku2         0    0.0
2017-06-02  sku2         0    0.0
2017-06-03  sku2        24    0.0

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将字符串的一部分从列复制到熊猫的新列中

如何用熊猫中的字典映射列值的一部分?

如何使用熊猫删除列值中的URL字符串的第一部分?

如何在熊猫中取一列的一部分与另一列的一部分匹配?

删除熊猫列中的一部分字符串

熊猫:从不同列中的元素替换字符串的一部分

定义列系列的一部分以在熊猫中建立索引

用熊猫重复用另一列的一部分填充一列的值

熊猫用字典中的值替换字符串的一部分

熊猫在两列的一部分上合并

在Python熊猫中选择列联表的一部分

熊猫只用日期时间索引替换列的一部分

删除熊猫列内的一部分字符串

满足条件的熊猫在列中删除n行,然后转到下一部分

如何将熊猫列与多索引数据框的一部分相乘

根据前两个字母替换熊猫数据框列的一部分

如何将熊猫数据框按自身的一部分划分?

熊猫read_csv防止文件中的引号成为数据的一部分

将列值划分为多个部分,并将部分名称存储在新的列熊猫中

大熊猫作为方程式的一部分获得两列的最小值

如何将熊猫数据帧的一部分替换为另一部分?

大熊猫用另一列替换一部分列

如何按熊猫中时间戳值的一部分进行分组?

SQL将列的一部分复制到新列中

将列值的一部分提取到新变量(突变)

熊猫用第一个可用值的一部分填充nan值

将分位数添加为熊猫中的新列

熊猫-将列值合并到新列的列表中

熊猫-将列值堆叠到新列中