簡體   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