![](/img/trans.png)
[英]How to find shared entries between two pandas data frames and use them to create an identical column in both data frames?
[英]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
來獲取每個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
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.