这看起来很简单,但我似乎无法弄明白。我知道如何将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
并获得其他所有内容?或者,更重要的是,我该怎么办才能获得其他所有东西。
答案 0 :(得分:3)
由于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