我试图在我的数据框中找到与此类似的相同订单 -
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 数据框中实现这一点?
样本输出类似于 -
Order_ID | SKU | Qty |Unique_Orders
[123] , [345]| [A],[B] | [1],[2] |2
[678] | [A],[C] | [1],[3] |1
感谢您的帮助。
答案 0 :(得分:2)
更新
基于问题的更新,这里是更新的答案,没有任何 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
总数和不同的 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}
答案 1 :(得分:2)
我们可以使用 groupby
+ unique
来获取每个 SKU
和 Qty
的唯一订单
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
答案 2 :(得分:1)
df.groupby(['SKU', 'Qty'])['Order_ID'].apply(list)
答案 3 :(得分:1)
另一个版本:
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
答案 4 :(得分:0)
在这种情况下您不需要使用组。只需使用 pandas 中的 duplicated() 函数即可。
df.duplicated()
这将返回一个布尔系列,其中第一个重复值显示为 True,其他类似值跟随第一个为 False。
因此,如果您想检索重复的 ID,只需遵循正常的 Pandas 条件即可。
df['Order_ID'].loc[df.duplicated()].values.unique()
假设 Order_ID 是 DataFrame 中的一列,并且默认的 id 列仍然存在。