根据 python 中另一列中的 AND 条件获取一列中的值

Get values in one column based on an AND condition in another column in python

我在 python 中有以下数据框,其中列名“Order_number”和“item_id”代表订单号和该订单中包含的项目。我需要获取由 item_ids A 和 B 组成的订单号,因此我的结果应该是订单号 12345 和 84573

Order_number item_id
12345 A
12345 B
34235 B
43543 B
84573 A
84573 B
45846 A

我有以下代码,但出现错误:

df[df['item_id'] == 'A' & df['item_id'] == 'B'] 

TypeError: Cannot perform 'rand_' with a dtyped [object] array and scalar of type [bool]

您可以 groupby.apply 一个 lambda 来检查每个“Order_number”的唯一“item_id”是否同时包含“A”和“B”;然后过滤那些:

out = df.groupby('Order_number')['item_id'].apply(lambda x: {'A','B'}.issubset(x.unique().tolist())).pipe(lambda x: x.index[x]).tolist()

另一种选择是使用groupby.any两次;一次为“A”,一次为“B”创建布尔系列对象,如果 Order_number 存在 item_id,则 return 为真;然后因为我们希望两者都存在,所以我们使用 & 并过滤 "Order_number"s:

out = (df['item_id'].eq('A').groupby(df['Order_number']).any() & df['item_id'].eq('B').groupby(df['Order_number']).any()).pipe(lambda x: x.index[x].tolist())

输出:

[12345, 84573]

我会按如下方式解决:按 order number 分组并创建一个集合。过滤器设置等于我们想要的。


(
  df
   .groupby("Order_number")
   .agg(set)
   .loc[lambda d: d['item_id'].eq({'A','B'})]
   .index
   .values
)

# results 
# array([12345, 84573])

如果是我们想要的子集,假设可以不止A和B,将过滤器.loc改为:

…
.loc[lambda d:d['item_id'].map({'A','B'}.issubset)]
…

# results 
# array([12345, 84573])

哦,如果你想要列表而不是数组,请将 .values 更改为 tolist()