【问题标题】:How to subtract two dataframes with duplicate first column?如何减去具有重复第一列的两个数据框?
【发布时间】:2021-10-22 18:41:06
【问题描述】:

所以,我有以下两个数据帧,我的理想输出是让 open_orders 减少 cancel_orders,这样我就知道我有多少 open_orders。

期望的输出:

df_total_orders
           order_id business_symbol  open_orders
0      a1b2c3111111              AA          0.0
1      4kl3l2242244             AAA          0.0
2      21312a224144             BBB          0.0
3      124f32rv2323             CCC          0.0
4      2412dfe21edf             DDD          0.0
5555

我现在拥有的:

df_add_orders (this dataframe contains duplicates in the order id column)
           order_id business_symbol  open_orders
0      a1b2c3111111              AA        100.0
1      4kl3l2242244             AAA       1000.0
2      21312a224144             BBB       1000.0
3      124f32rv2323             CCC       1000.0
4      2412dfe21edf             DDD       1000.0
10000
df_cancel_orders (this dataframe contains duplicates in the order id column)
           order_id   cancel_orders
0      a1b2c3111111           100.0
1      4kl3l2242244          1000.0
2      21312a224144          1000.0
3      124f32rv2323          1000.0
4      2412dfe21edf          1000.0
4000

我正在使用以下 group by 来获取未结订单总数,但它会在输出中删除我的符号。

df_add_orders_group = df_add_orders.groupby(['order_id'], as_index=False)['open_orders'].sum()

df_add_orders_group
           order_id        open_orders
0      a1b2c3111111              110.0
1      4kl3l2242244             1200.0
2      21312a224144             1500.0
3      124f32rv2323             1500.0
4      2412dfe21edf             1500.0
5000

然后我减去已关闭的订单

df_cancel_orders_group = df_cancel_orders.groupby(['order_id'], as_index=False)['cancel_orders'].sum()

但我想保留符号,以便比较未结订单的总数,我需要一些方法将减法的结果与主 df_add_orders 合并,并清理 order_id 以对重复项求和。

【问题讨论】:

  • 当您的df_add_ordersdf_cancel_orders 完全相同时,您如何获得该输出?你的输出不应该在open_orders 中全为零吗?
  • 这是一个例子,但是在这种情况下它是零。我更新了。
  • 这能回答你的问题吗? "Anti-merge" in pandas (Python)

标签: python pandas dataframe


【解决方案1】:
df_total_orders =df_add_orders.merge(df_cancel_orders, 
    how = 'left', 
    on = 'order_id)

将为您提供一个包含来自两个原始数据帧的数据的数据帧。然后你可以做

df_total_orders['open_orders'] = 
    df_total_orders['open_orders']-
    df_total_orders['cancel_orders']

然后删除cancel_order 列。

另一种策略是将两个原始数据帧附加在一起。然后,您可以对 id 和 sum 进行 groupby。这将创建一个数据框,对于每个 ID,一列是该 ID 所有未结订单的总和,另一列是该 ID 所有取消订单的总和。然后,您可以获取两列之间的差异。

当你追加两个数据帧时,你会得到一堆空值;来自未结订单的部分将在取消订单列中为空,反之亦然。我认为对 groupby 求和只会将空值视为零,但您可能需要明确告诉它这样做。

【讨论】:

  • OP 已指定 df_add_ordersdf_cancel_orders 有重复的 order_id 所以 merge 显然不起作用。
【解决方案2】:

试试pandas.mergegroupby

merged = pd.merge(df_add_orders.groupby("order_id", as_index=False) \
                               .agg({"business_symbol": "first", 
                                     "open_orders": "sum"}), 
                 df_cancel_orders.groupby("order_id", as_index=False).sum(), 
                 on="order_id")

output = merged.assign(open_orders=merged["open_orders"]-merged["cancel_orders"]) \
               .drop("cancel_orders", axis=1)

>>> output
       order_id business_symbol  open_orders
0  124f32rv2323             CCC          0.0
1  21312a224144             BBB          0.0
2  2412dfe21edf             DDD          0.0
3  4kl3l2242244             AAA          0.0
4  a1b2c3111111              AA          0.0

【讨论】:

    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 2021-12-07
    • 2018-06-29
    • 2017-02-20
    • 2023-03-06
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    相关资源
    最近更新 更多