【问题标题】:Pandas groupby multiple columns and retain all other columnsPandas 按多列分组并保留所有其他列
【发布时间】:2020-05-11 22:47:24
【问题描述】:

我有一个 df,它是两个结构相同的 df 的 concat,第一个是 Orders,第二个是 CancelsOrders 中有超过 20,000 行,少数 Cancels 有对应的 OrderNoItemCode。我已将取消的数量设为负数,因此在将 df 按OrderNoItemCode 分组时,我可以将数量字段与agg 相加,从而为我提供实际的发货数量,以补偿取消的订单。

下面是我的数据框:

    OrderNo     OrderDate   LineNo  ClientNo    ItemCode    QtyOrdered  QtyShipped
0   528758  1/3/2017    1   1358538     111931  70  70
1   528791  1/3/2017    10  1254798     110441  300     300
2   528791  1/3/2017    1   1254798     1029071     10  10
3   528791  1/3/2017    2   1254798     1033341     10  10
4   528791  1/3/2017    8   1254798     1040726     15  15
...     ...     ...     ...     ...     ...     ...     ...
28344   537667  2/6/2017    12  43823870    10137992    0   -2
28345   537771  2/7/2017    5   1276705     1041106     0   -4
28346   539524  2/13/2017   6   1254798     1038323     0   -10
28347   542362  2/23/2017   11  1254612     1041108     0   -2
28348   542835  2/23/2017   13  1255235     10137993    0   -5

28349 rows × 7 columns

运行后:

ActualOrders = PreActualOrders.groupby(['OrderNo','ItemCode']).agg({'QtyOrdered': 'sum', 'QtyShipped': 'sum'}).reset_index()

我得到了我想要的结果,但我丢失了 DF 中的所有其他列。

结果示例如下:

    OrderNo     ItemCode    QtyOrdered  QtyShipped
28255   543734  1038324     1   1
28256   543734  10137992    1   1
28257   543734  10137993    1   1
28258   543735  1041106     1   1
28259   543735  1041108     1   1
28260   543735  10135359    1   1

我需要添加什么才能将所有列保留在原始 df 中?

那些其他列中的所有值都匹配,因为它们是相应的取消或订单。

谢谢,

MTH

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    如果我对您的理解正确,您可以尝试不使用 groupby 的另一种方法。 类似的东西:

    orders = [["123", "1", 10], ["1234", "2", 100], ["12345", "3", 15]]
    cancels = [["123", "1", 10]]
    
    df_orders = pd.DataFrame(orders, columns=["OrderNo", "ItemCode", "Amount"])
    df_cancels = pd.DataFrame(cancels, columns=["OrderNo", "ItemCode", "Amount"])
    
    merged = df_orders.merge(df_cancels, how="left", on=["OrderNo", "ItemCode"], suffixes=["_orders", "_cancels"])
    merged["Amount_cancels"] = merged["Amount_cancels"].fillna(0)
    print("Before substract cancels")
    print(merged)
    
    merged["Amount_orders"] = merged["Amount_orders"] - merged["Amount_cancels"]
    print("After substract cancels")
    print(merged)
    

    【讨论】:

      【解决方案2】:

      通过在 'first' 中包含 agg 函数中的其他列,而“QtyOrdered”和“QtyShipped”受 'sum' 约束,我能够获得所需的结果。

      ActualOrders = PreActualOrders.groupby(['OrderNo','ItemCode']).agg({'OrderDate': 'first', 'LineNo': 'first', 'ClientNo': 'first', 'QtyOrdered': 'sum', 'QtyShipped': 'sum' }).reset_index()

      产生我想要的结果:

            OrderNo   ItemCode    OrderDate LineNo ClientNo QtyOrdered QtyShipped
      28255   543734  1038324     2/27/2017   3   1254787     1   1
      28256   543734  10137992    2/27/2017   1   1254787     1   1
      28257   543734  10137993    2/27/2017   2   1254787     1   1
      28258   543735  1041106     2/27/2017   4   1816460     1   1
      28259   543735  1041108     2/27/2017   3   1816460     1   1
      28260   543735  10135359    2/27/2017   2   1816460     1   1
      28261   543735  10137993    2/27/2017   1   1816460     1   1
      

      输出示例没有显示订购数量和发货数量之间的任何差异,因为匹配取消的数量非常少。具有相应取消的行已正确调整。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-10
        • 2012-01-03
        • 2020-04-21
        • 2022-11-23
        • 1970-01-01
        • 2021-09-09
        • 2021-10-02
        相关资源
        最近更新 更多