将 Pandas 列与一长串元组进行比较

law*_*son 5 python pandas

假设我们有一长串由坐标组成的元组:

coords = 
[(61.0, 73, 94.0, 110.0),
(61.0, 110.0, 94.0, 148.0), 
(61.0, 148.0, 94.0, 202.0), 
(61.0, 202.0, 94.0, 241.0).......]
Run Code Online (Sandbox Code Playgroud)

我们的数据框有多个列,包括对应于坐标的“左、上、左1、上1”。

    left    top     left1   top1
0   398     57.0    588     86
1   335     122.0   644     145
2   414     150.0   435     167
3   435     150.0   444     164
4   444     150.0   571     167
...     ...     ...     ...     ...
Run Code Online (Sandbox Code Playgroud)

我想检查哪些行落在这些坐标内。我目前正在一次执行一个元组,如下所示,但这非常慢。

for coord in coords:
    result = df.loc[(df['left']>(coord[0])) &
                    (df['left1']<=(coord[2])) & 
                    (df['top1']>(coord[1])) & 
                    (df['top']<(coord[3]))]
Run Code Online (Sandbox Code Playgroud)

有没有更快的方法来做到这一点?

非常感谢所有贡献者!

WeN*_*Ben 1

我们可以做numpy广播

df=df.reindex(columns=['left','top1','left1','top'])
a=np.sign(df.values - np.array(coords)[:, None]) 
idx=np.any(np.all(np.sign(a)==np.array([1,1,-1,-1]),2),0) |np.any(np.all(np.sign(a)==np.array([1,1,0,-1]),2),0)
idx
Out[237]: array([ True, False, False, False, False])

df_sub=df[idx]
Run Code Online (Sandbox Code Playgroud)

例如

df
Out[231]: 
    left    top1  left1    top
0  10000  100000      0    0.0
1    335     145    644  122.0
2    414     167    435  150.0
3    435     164    444  150.0
4    444     167    571  150.0
Run Code Online (Sandbox Code Playgroud)

你的输出

for coord in coords:
    result = df.loc[(df['left']>(coord[0])) &
                    (df['left1']<=(coord[2])) & 
                    (df['top1']>(coord[1]))
                    & 
                    (df['top']<(coord[3]))]

result
Out[228]: 
    left  top  left1    top1
0  10000  0.0      0  100000
Run Code Online (Sandbox Code Playgroud)

我的输出

df_sub = df[idx]
print(df_sub)
    left    top1  left1  top
0  10000  100000      0  0.0
Run Code Online (Sandbox Code Playgroud)