【问题标题】:Pandas boolean indexing vs comparision of two lists: Same (?) methods, different resultsPandas 布尔索引与两个列表的比较:相同的(?)方法,不同的结果
【发布时间】:2015-09-14 22:56:29
【问题描述】:

我有一个名为 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 的行。

方法一:

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

方法二:

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 其他案例,我无法弄清楚这些案例是什么。

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

【问题讨论】:

  • bom2[-...] 中,减号是故意的吗?如果是这样,你的意思是什么?
  • 是的,减号或者 ~ 充当逻辑非(否定),所以 -True == False 和 -False == True 如stackoverflow.com/questions/14057007/remove-rows-not-isinx
  • 有趣。我一直使用~,但不知道- 做同样的事情。谢谢。

标签: python pandas


【解决方案1】:

考虑以下玩具示例:

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 中的 IDS。
  • 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 在 装配柱使用方法一:

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

不是方法二:

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

【讨论】:

    【解决方案2】:

    这与方法 1 和方法 2 无关,因此与编程技术无关,而是与逻辑有关。更重要的是,我有一个想法,如果您在第二种方法中使用布尔索引/过滤,您将获得相同的结果,反之亦然。 这是因为,如果我们将每个列表中的一些唯一值合并,每个列表中都会有相同的值,这些值在 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
    

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

    【讨论】:

      猜你喜欢
      • 2019-05-28
      • 1970-01-01
      • 2013-08-27
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多