gpt4 book ai didi

python - 在 pandas 数据帧上应用 np.isin() 时出现意外行为

转载 作者:行者123 更新时间:2023-12-01 00:55:15 26 4
gpt4 key购买 nike

工作时on an answer to another question ,我偶然发现了一个意想不到的行为:

考虑以下 DataFrame:

df = pd.DataFrame({
'A':list('AAcdef'),
'B':[4,5,4,5,5,4],
'E':[5,3,6,9,2,4],
'F':list('BaaBbA')
})
print(df)
   A  B  E  F
0 A 4 5 B #<— row contains 'A' and 5
1 A 5 3 a #<— row contains 'A' and 5
2 c 4 6 a
3 d 5 9 B
4 e 5 2 b
5 f 4 4 A

如果我们尝试查找包含 ['A', 5] 的所有列,我们可以使用jezrael's answer :

cond = [['A'],[5]]
print( np.logical_and.reduce([df.isin(x).any(1) for x in cond]) )

(正确地)产生:[ True True False False False False]

如果我们使用:

cond = [['A'],[5]]
print( df.apply(lambda x: np.isin([cond],[x]).all(),axis=1) )

这会产生:

0    False
1 False
2 False
3 False
4 False
5 False
dtype: bool

对第二次尝试的仔细检查表明:

  • np.isin(['A',5],df.loc[0]) “错误”产量 array([ True, False]) ,可能是由于 numpy推断数据类型 <U1 ,因此 5!='5'
  • np.isin(['A',5],['A',4,5,'B']) “正确”产生array([ True, True]) ,这意味着我们可以(并且应该)使用 df.loc[0].values.tolist().apply()上面的方法

简化后的问题:

为什么我需要指定x.values.tolist()在一种情况下,可以直接使用x在另一个?

print( np.logical_and.reduce([df.isin(x).any(1) for x in cond]) )
print( df.apply(lambda x: np.isin([cond],x.values.tolist()).all(),axis=1 ) )

编辑:

更糟糕的是,如果我们搜索 [4,5] 会发生什么:

cond = [[4],[5]]
## this returns False for row 0
print( df.apply(lambda x: np.isin([cond],x.values.tolist() ).all() ,axis=1) )
## this returns True for row 0
print( df.apply(lambda x: np.isin([cond],x.values ).all() ,axis=1) )

最佳答案

我认为在DataFrame中混合了数字和整数列,所以如果按行循环得到具有混合类型的Series,那么numpy将其强制转换为字符串

可能的解决方案是转换为数组,然后转换为 cond 中的 string 值:

cond = [[4],[5]]

print(df.apply(lambda x: np.isin(np.array(cond).astype(str), x.values.tolist()).all(),axis=1))
0 True
1 False
2 False
3 False
4 False
5 False
dtype: bool

不幸的是,对于一般解决方案(如果可能的话,只有数字列)需要同时转换 - condSeries:

f = lambda x: np.isin(np.array(cond).astype(str), x.astype(str).tolist()).all()
print (df.apply(f, axis=1))

或所有数据:

f = lambda x: np.isin(np.array(cond).astype(str), x.tolist()).all()
print (df.astype(str).apply(f, axis=1))

如果在纯Python中使用集合,它工作得很好:

print(df.apply(lambda x: set([4,5]).issubset(x),axis=1) )
0 True
1 False
2 False
3 False
4 False
5 False
dtype: bool

print(df.apply(lambda x: set(['A',5]).issubset(x),axis=1) )
0 True
1 True
2 False
3 False
4 False
5 False
dtype: bool

关于python - 在 pandas 数据帧上应用 np.isin() 时出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56288089/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com