在所有行上过滤不符合条件的pandas数据框。

9

这看起来很简单,但我似乎想不出来。我知道如何过滤 Pandas 数据框以满足条件的所有行,但是当我想要相反时,我一直得到奇怪的错误。

这里是一个例子。(背景:一个简单的棋盘游戏,其棋子在网格上,我们正在尝试给出一个坐标并返回所有相邻的棋子,但不包括该坐标上的实际棋子)

import pandas as pd
import numpy as np

df = pd.DataFrame([[5,7, 'wolf'],
              [5,6,'cow'],
              [8, 2, 'rabbit'],
              [5, 3, 'rabbit'],
              [3, 2, 'cow'],
              [7, 5, 'rabbit']],
              columns = ['lat', 'long', 'type'])

coords = [5,7] #the coordinate I'm testing, a wolf

view = df[((coords[0] - 1) <= df['lat']) & (df['lat'] <= (coords[0] + 1)) \
    & ((coords[1] - 1) <= df['long']) & (df['long'] <= (coords[1] + 1))]

view = view[not ((coords[0] == view['lat']) & (coords[1] == view['long'])) ] 

print(view)

我原以为not只会否定圆括号内的布尔值,但实际情况并非如此。

我想返回坐标为5,6的牛,但不包括坐标为5,7的狼(因为它是当前棋子)。为了再次确认我的逻辑,我进行了以下操作:

me = view[(coords[0] == view['lat']) & (coords[1] == view['long'])] 
print(me)

然后返回了我预期的仅为狼。那么,我为什么不能在前面加上一个not来获取其他所有东西呢?或者,更重要的是,我该怎么做才能获取其他所有东西。

1个回答

17

由于numpy(因此也包括pandas)使用位运算符,您应该将not替换为~。这也是您使用&而不是and的原因。

import pandas as pd

df = pd.DataFrame({'a': [1, 2]})

print(df[~(df['a'] == 1)])
>>    a
   1  2

并使用您的示例:

import pandas as pd
import numpy as np

df = pd.DataFrame([[5,7, 'wolf'],
              [5,6,'cow'],
              [8, 2, 'rabbit'],
              [5, 3, 'rabbit'],
              [3, 2, 'cow'],
              [7, 5, 'rabbit']],
              columns = ['lat', 'long', 'type'])

coords = [5,7] #the coordinate I'm testing, a wolf

view = df[((coords[0] - 1) <= df['lat']) & (df['lat'] <= (coords[0] + 1)) \
    & ((coords[1] - 1) <= df['long']) & (df['long'] <= (coords[1] + 1))]

view = view[~ ((coords[0] == view['lat']) & (coords[1] == view['long'])) ] 

print(view)
>>    lat  long type
   1    5     6  cow

是的!谢谢。我之前也尝试过使用 !,因为我认为可能会发生这样的事情,但我还是有点偏离了。再次感谢。 - seth127
1
使用 .isin() 方法可以帮助子集化大量项目。df = df[~(df['my column'].isin(['item1','item2']))] - kevin_theinfinityfund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接