两个列表的布尔索引与比较:相同(?)方法,不同的结果

2024-06-16 11:24:54 发布

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

我有一个名为bom2的表(约74k行+其他列),但我们只对组装和成品感兴趣。为了更清楚一点,两列中可以显示相同的装配和成品ID。你知道吗

  bom2=pd.DataFrame({'Assembly': {0: '0138104116',
  1: '0309005994',
  2: '0309005996',
  3: '0309005998',
  4: '0309005998',
  5: '0309005998',
  6: '0309005998',
  7: '0312005996',
  8: '0312005997',
  9: '0312005998'},
 'Finish product': {0: '0138104116',
  1: '0309005994',
  2: '0309005996',
  3: '0309005998',
  4: '0309005998',
  5: '0309005998',
  6: '0309005998',
  7: '0312005996',
  8: '0312005997',
  9: '0312005998'}})

我需要:

获取所有程序集ID

与成品ID比较

只取Finish product在Assembly列中没有其ID的行。你知道吗

方法1:

nejsou = bom2[-bom2['Finish product'].isin(bom2.Assembly.tolist())] 

方法2:

ass = bom2.Assembly.tolist()
fin = bom2['Finish product'].tolist()
nee=list()  #will contain Assembly IDs which do not occur in 'Finish product'
for a in ass:
    if a not in fin: nee.append(a)

在下一步中,使用“nee”中的id按

bom2[bom2.Assembly.isin(nee)]

我原以为这两个方法是等价的,但是当我检查每个方法产生的程序集ID的数量时,我得到了不同的数字。你知道吗

print "method(1 + 2):", len(set(nejsou.Assembly.tolist()+nee)), "Unique Assembly IDs"
print "method(1):",len(set(nejsou.Assembly.tolist())), "Unique Assembly IDs"
print "method(2):",len(set(nee)), "Unique Assembly IDs"

method(1 + 2): 4021 Unique Assembly IDs
method(1): 4015 Unique Assembly IDs
method(2): 1986 Unique Assembly IDs

似乎方法1(布尔过滤)捕获了方法2捕获的所有案例+大约2k个其他案例,而我不知道这些案例是什么。你知道吗

这两种方法有何不同? 有没有其他方法可以达到预期的效果?你知道吗


Tags: 方法inididsassemblyproductmethodunique
2条回答

考虑以下玩具示例:

import numpy as np
import pandas as pd

bom2 = pd.DataFrame(
    [
        ['A', 'F'],
        ['AF', 'F'],

        ['AF2', 'F'],   
        ['A', 'AF2'], 

        ['A', 'AF'],
        ['A2', 'AF'],

    ], columns=['ASS', 'FIN'])

print(bom2)
#    ASS  FIN
# 0    A    F
# 1   AF    F
# 2  AF2    F
# 3    A  AF2
# 4    A   AF
# 5   A2   AF

“模式”是:

  • AFAF2指的是在ASS和FIN中的id。你知道吗
  • AA2只在ASS中
  • F只在FIN中。你知道吗

然后:

ass = bom2['ASS'].tolist()
fin = bom2['FIN'].tolist()

# filter out rows of bom2 where FIN equals AF
nejsou = bom2[-bom2['FIN'].isin(ass)] 

nee = list()  #will contain ASS not in FIN
for a in ass:
    if a not in fin: nee.append(a)

print(nejsou)
#    ASS FIN
# 0    A   F
# 1   AF   F
# 2  AF2   F

收益率

print "method(1 + 2):", len(set(nejsou.ASS.tolist()+nee)), "Unique ASS IDs"
# method(1 + 2): 4 Unique ASS IDs

print "method(1):",len(set(nejsou.ASS.tolist())), "Unique ASS IDs"
# method(1): 3 Unique ASS IDs

print "method(2):",len(set(nee)), "Unique ASS IDs"
# method(2): 2 Unique ASS IDs

注意

print(set(nee))
# set(['A', 'A2'])

print(set(nejsou.ASS.tolist()))
# set(['A', 'AF2', 'AF'])

所以方法(1)和方法(2)产生不同的结果。 如果您遵循此模式,您可以在其中添加任意数量的项 设置。你知道吗

  • 要增加方法(1)而不增加方法(2),请添加更多行,如AF

    ['AFn', 'F'],
    ['A', 'AFn'],
    
  • 要增加方法(2)而不增加方法(1),请添加更多行,如A2

    ['An', 'AF'], 
    

仅获取Finish product在 装配柱使用方法1:

In [107]: bom2.loc[~bom2['FIN'].isin(bom2['ASS'])]
Out[107]: 
   ASS FIN
0    A   F
1   AF   F
2  AF2   F

不是方法2:

In [109]: bom2[bom2['ASS'].isin(nee)]
Out[109]: 
  ASS FIN
0   A   F
4   A  AF  <  WRONG; AF is in bom2['ASS']
5  A2  AF  <  WRONG

这与方法1和方法2无关,因此与编程技术无关,而与逻辑有关。此外,我有一个想法,你会得到同样的结果,如果你使用布尔索引/过滤在第二种方法,反之亦然。 这是因为,如果我们将too列表与每个列表中的一些唯一值合并,那么在set()函数之后,每个列表中将有相同的值,这些值将变成一个值而不是两个值。你知道吗

考虑以下示例:

a = [1,2,3]
b = [3,4,5]

print set(a)
print set(b)
print
print len(set(a))
print len(set(b))
print
print set(a+b)
print
print len(set(a+b))

输出:

set([1, 2, 3])
set([3, 4, 5])

3
3

set([1, 2, 3, 4, 5])

5

很高兴能帮上忙!如果你觉得我的回答对你有用,请随时接受。:-)

相关问题 更多 >