繁体   English   中英

在 python 数据帧 pandas 中查找相同的组

[英]Find identical groups in python data frames pandas

我试图在我的 dataframe 中找到相同的订单,看起来与此类似 -

Order_ID |SKU |Qty |

123 | A | 1 |

123 | B | 2 |

345 | A | 1 |

345 | B | 2 |

678 | A | 1 |

678 | C | 3 |

一个订单可以有多个SKU,即1个订单可以有多行。 所以包含确切 SKU 和数量的 order_ID 是相同的。 这里是 123 和 345。我需要与 SKU 和数量相同的订单。

如何使用分组在 pandas dataframe 中实现这一点?

样品 Output 将类似于 -

Order_ID     |   SKU    | Qty        |Unique_Orders
[123] , [345]| [A],[B]  | [1],[2]    |2
[678]        | [A],[C]  | [1],[3]    |1

谢谢你的帮助。

更新

根据问题中的更新,这是一个更新的答案,没有任何 Python 级循环:

skuqty = df.groupby('Order_ID')[['SKU', 'Qty']].agg(tuple).reset_index()
skuqty.groupby(['SKU', 'Qty'])['Order_ID'].unique().reset_index()

这使:

      SKU     Qty    Order_ID
0  (A, B)  (1, 2)  [123, 345]
1  (A, C)  (1, 3)       [678]

或者,如果您想完全匹配您的规格,您可以进一步执行以下操作:

z = skuqty.groupby(['SKU', 'Qty'])['Order_ID'].unique().reset_index()
z = z.assign(SKU=z['SKU'].apply(list)).assign(Qty=z['Qty'].apply(list)).assign(Unique_Orders=z['Order_ID'].apply(len))
z = z[['Order_ID', 'SKU', 'Qty', 'Unique_Orders']]

这使:

>>> z
     Order_Id     SKU     Qty  Unique_Orders
0  [123, 345]  [A, B]  [1, 2]              2
1       [678]  [A, C]  [1, 3]              1

速度

这是相对较快的:

n = 1_000_000
df = pd.DataFrame({
    'Order_ID': np.random.randint(0, 999, n),
    'SKU': np.random.choice(list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), n),
    'Qty': np.random.randint(1, 100, n),
})

%timeit proc(df)  # which is the (first) code above
# 405 ms ± 407 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

原始答案

这取决于你想对这些组做什么。 这是一个汇总Qty的示例:

df.groupby('Order_ID')['Qty'].sum()

给出:

Order_ID
123    3
345    3
678    4
Name: Qty, dtype: int64

或者,如果您想同时查看Qty total 和不同的SKU

>>> df.groupby('Order_ID').agg({'Qty':sum, 'SKU':'unique'})
          Qty     SKU
Order_ID             
123         3  [A, B]
345         3  [A, B]
678         4  [A, C]

最后,有一个为每个dict提供{SKU: Qty}Order_ID

>>> df.groupby('Order_ID').apply(lambda g: dict(g[['SKU', 'Qty']].values))
Order_ID
123    {'A': 1, 'B': 2}
345    {'A': 1, 'B': 2}
678    {'A': 1, 'C': 3}

我们可以使用groupby + unique来获取每个SKUQty的唯一订单

df.groupby(['SKU', 'Qty'])['Order_ID'].unique()

如果您还想count unique订单的数量,那么我们可以另外使用nunique

df.groupby(['SKU', 'Qty'])['Order_ID'].agg(['unique', 'nunique'])

                  unique  nunique
SKU Qty                          
A   1    [123, 345, 678]        3
B   2         [123, 345]        2
C   3              [678]        1
df.groupby(['SKU', 'Qty'])['Order_ID'].apply(list)

另一个版本:

x = df.groupby("Order_ID")[["SKU", "Qty"]].apply(
    lambda x: frozenset(zip(x.SKU, x.Qty))
)

df_out = pd.DataFrame(
    [
        {
            "Order_ID": v.to_list(),
            "SKU": [sku for sku, _ in k],
            "Qty": [qty for _, qty in k],
            "Unique_Orders": len(v),
        }
        for k, v in x.index.groupby(x).items()
    ]
)
print(df_out)

印刷:

     Order_ID     SKU     Qty  Unique_Orders
0  [123, 345]  [A, B]  [1, 2]              2
1       [678]  [C, A]  [3, 1]              1

在这种情况下,您不需要使用组。 只需在 pandas 中使用 duplicated() function。

df.duplicated()

这将返回一个 boolean 系列,其中第一个重复值显示为 True,其他类似的值跟随第一个为 False。

因此,如果您想检索重复的 ID,只需遵循正常的 pandas 条件即可。

df['Order_ID'].loc[df.duplicated()].values.unique()

假设 Order_ID 是 DataFrame 中的一列,并且默认的 id 列仍然存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM