如果另一列中的值是唯一的,则在一列中搜索条件,并将结果写入第三列



我有一个包含70k行和两列的数据帧。Col1包含物料清单名称和客户,Col2包含零件号(它是BOM的一部分(。

Col1  Col2
0  TUR, Cust1  1001
1  GAR, Cust2  1001
2  FOR, Cust3  1001
3  ERB, Cust1  1002
4  PNR, Cust1  1002
5  DUL, Cust2  1003
6  COC, Cust3  1003
7  ETM, Cust1  1004
8  ROW, Cust3  1005
9  HON, Cust3  1005 

在搜索Cust1时,我想在第3列中查看零件号是否是专门为该客户购买的。类似这样的东西:

Col1  Col2   Col3
0  TUR, Cust1  1001  false
1  GAR, Cust2  1001  false
2  FOR, Cust3  1001  false
3  ERB, Cust1  1002   true
4  PNR, Cust1  1002   true
5  DUL, Cust2  1003  false
6  COC, Cust3  1003  false
7  ETM, Cust1  1004   true
8  ROW, Cust3  1005  false
9  HON, Cust3  1005  false

我已经尝试过用df.duplated提取重复项,并用str.contains评估客户名称,但没有得到令人满意的结果。有没有我不知道的聪明的解决方案?我是python的新手,遇到这个问题毫无进展。

Col1中提取客户,然后从groupby中提取零件号,并计算应等于1 的唯一客户数

df['Cust'] = df['Col1'].str.split(', ').str[-1]
df['Col3'] = df.groupby('Col2')['Cust'].transform('nunique').eq(1)

如果只想在一次考虑一个客户的情况下检查重复,这里有一个更简单的版本

m = df['Col1'].str.split(', ').str[-1] == 'Cust1' # is cust1?
df['Col3'] = m.groupby(df['Col2']).transform('all') # are all cust1 per part?

结果

Col1  Col2   Cust   Col3
0  TUR, Cust1  1001  Cust1  False
1  GAR, Cust2  1001  Cust2  False
2  FOR, Cust3  1001  Cust3  False
3  ERB, Cust1  1002  Cust1   True
4  PNR, Cust1  1002  Cust1   True
5  DUL, Cust2  1003  Cust2  False
6  COC, Cust3  1003  Cust3  False
7  ETM, Cust1  1004  Cust1   True

一种方法如下:

df['Col3'] = df.Col1.str.extract(r',s(.*)$')[0]
# or: `df['Col1'].str.split(', ', expand=True)[1]`
df['Col3'] = df.Col2.map(df.drop_duplicates(subset=['Col2','Col3'])
['Col2'].value_counts().eq(1))
print(df)
Col1  Col2   Col3
0  TUR, Cust1  1001  False
1  GAR, Cust2  1001  False
2  FOR, Cust3  1001  False
3  ERB, Cust1  1002   True
4  PNR, Cust1  1002   True
5  DUL, Cust2  1003  False
6  COC, Cust3  1003  False
7  ETM, Cust1  1004   True

解释

  • 使用Series.str.extractCol1获取客户名称,并分配给新列Col3。(或者,使用Series.str.split。(
  • 接下来,使用df.drop_duplicatessubset参数设置为['Col2','Col3']。例如,对于1002, Cust1这样的副本,我们只保留第一个
  • 现在,选择Col2并应用Series.value_countsdf.drop_duplicates(subset=['Col2','Col3'])['Col2'].value_counts()在此阶段的结果如下:
1001    3
1003    2
1002    1
1004    1
Name: Col2, dtype: int64
  • 1为计数的Col2中的值(即1002, 1004(将仅出现在一个客户中,因此我们可以将Series.eq链接为仅针对这些值返回True,而将False链接为其他值
  • 最后,我们想把这个结果放在Series.map中,应用于Col2以匹配正确的布尔值。用结果重新覆盖Col3

最新更新