![](/img/trans.png)
[英]Pandas groupby with value_counts and generating columns in new dataframe
[英]Filter Pandas DataFrame using value_counts and multiple columns?
我有一个订单数据集和下订单的人。 订单具有唯一标识符,买家在多个订单中具有唯一标识符。 这是该数据集的示例:
| Order_ID | Order_Date | Buyer_ID |
|----------|------------|----------|
| 123421 | 01/01/19 | a213422 |
| 123421 | 01/01/19 | a213422 |
| 123421 | 01/01/19 | a213422 |
| 346345 | 01/03/19 | a213422 |
| 567868 | 01/05/19 | a346556 |
| 567868 | 01/05/19 | a346556 |
| 234534 | 01/10/19 | a678909 |
我希望能够将数据集过滤到只下过一个订单的个人,即使该订单有多个项目:
| Order_ID | Order_Date | Buyer_ID |
|----------|------------|----------|
| 567868 | 01/05/19 | a346556 |
| 567868 | 01/05/19 | a346556 |
| 234534 | 01/10/19 | a678909 |
如果我尝试df[df['Buyer_ID'].map(df['Buyer_ID'].value_counts()) == 1]
我会遇到一个非常奇怪的情况,结果数据框只是其中存在 1 到 1 关系的行Order_ID
和Buyer_ID
。 像这样:
| Order_ID | Order_Date | Buyer_ID |
|----------|------------|----------|
| 346345 | 01/03/19 | a213422 |
| 234534 | 01/10/19 | a678909 |
在我想要的结果中, Buyer_ID
a213422
根本不应该出现,因为那个人有多个Order_ID
。
这让我相信value_counts()
要么不是执行此过滤器的合适方法,要么我做错了。 执行此过滤器的适当方法是什么?
方法 1:使用groupby.transform
布尔索引
df[df.groupby('Buyer_ID')['Order_ID'].transform('nunique').eq(1)]
方法二: Groupby.filter
df.groupby('Buyer_ID').filter(lambda x: x['Order_ID'].nunique()==1)
方法 3:使用Series.map
boolean indexing
df[df['Buyer_ID'].map(df.groupby('Buyer_ID')['Order_ID'].nunique().eq(1))]
输出
Order_ID Order_Date Buyer_ID
4 567868 01/05/19 a346556
5 567868 01/05/19 a346556
6 234534 01/10/19 a678909
如果要删除重复DataFrame.drop_duplicates
,请在最后使用DataFrame.drop_duplicates
:
df[df.groupby('Buyer_ID')['Order_ID'].transform('nunique').eq(1)].drop_duplicates()
Order_ID Order_Date Buyer_ID
4 567868 01/05/19 a346556
6 234534 01/10/19 a678909
这是您可以执行的另一种方法:
import pandas as pd
# | Order_ID | Order_Date | Buyer_ID |
# |----------|------------|----------|
# | 123421 | 01/01/19 | a213422 |
# | 123421 | 01/01/19 | a213422 |
# | 123421 | 01/01/19 | a213422 |
# | 346345 | 01/03/19 | a213422 |
# | 567868 | 01/05/19 | a346556 |
# | 567868 | 01/05/19 | a346556 |
# | 234534 | 01/10/19 | a678909 |
df = pd.DataFrame.from_dict({
"Order_ID": [123421, 123421, 123421, 346345, 567868, 567868, 234534],
"Order_Date": ["01/01/19", "01/01/19", "01/01/19", "01/03/19", "01/05/19", "01/05/19", "01/10/19"],
"Buyer_ID": ["a213422", "a213422", "a213422", "a213422", "a346556", "a346556", "a678909"],
})
buyers_with_one_order = df.groupby(["Buyer_ID"]) \
.agg(num_orders=("Order_ID", pd.Series.nunique)) \
.query("num_orders == 1") \
.reset_index() \
.Buyer_ID
filtered_df = df.merge(buyers_with_one_order).drop_duplicates()
print(filtered_df.to_string(index=False))
# | Order_ID | Order_Date | Buyer_ID |
# |----------|------------|----------|
# | 567868 | 01/05/19 | a346556 |
# | 234534 | 01/10/19 | a678909 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.