使用值\计数和多列筛选数据帧?

2024-09-28 21:00:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个订单数据集和下订单的人。订单有一个唯一的标识符,买家在多个订单中有一个唯一的标识符。下面是该数据集的一个示例:

| 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],我会得到一个非常奇怪的情况,结果数据帧只是Order_IDBuyer_ID之间存在1对1关系的行。像这样:

| Order_ID | Order_Date | Buyer_ID |
|----------|------------|----------|
| 346345   | 01/03/19   | a213422  |
| 234534   | 01/10/19   | a678909  |

在我想要的结果中,Buyer_IDa213422根本不应该出现,因为那个人有多个Order_ID。你知道吗

这让我相信value_counts()不是执行此筛选器的合适方法,或者我做得不对。执行此筛选的适当方法是什么?你知道吗


Tags: 数据方法订单iddfdatevalueorder
2条回答

下面是另一种方法:

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  |

方法1:布尔索引与groupby.transform

df[df.groupby('Buyer_ID')['Order_ID'].transform('nunique').eq(1)]

方法2:^{}

df.groupby('Buyer_ID').filter(lambda x: x['Order_ID'].nunique()==1)

方法3:boolean indexingSeries.map

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

如果要删除重复项,请在末尾使用^{}

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

相关问题 更多 >