Python 比较pandas列与长元组列表

Python 比较pandas列与长元组列表,python,pandas,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).......] 我们的数据框架有多个列,包括对应于坐标的“left、top、left1、top1” left top left1 top1 0 398 57.0 588

假设我们有一个由坐标组成的元组长列表:

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).......]
我们的数据框架有多个列,包括对应于坐标的“left、top、left1、top1”

    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
...     ...     ...     ...     ...
我想检查哪些行在这些坐标范围内。我现在一次只做一个元组,如下所示,但速度非常慢

for coord in coords:
    result = df.loc[(df['left']>(coord[0])) &
                    (df['left1']<=(coord[2])) & 
                    (df['top1']>(coord[1])) & 
                    (df['top']<(coord[3]))]
对于协调中的协调:
结果=df.loc[(df['left']>(coord[0]))&
(df['left1'](coord[1])和

(df['top']执行此操作的一种方法是交叉连接,然后是筛选器:

coord_df = pd.DataFrame(coords, columns=['left', 'top', 'left1', 'top1'])

# We need to assign dummies for the cross join
coord_df['dummy'] = 1
df['dummy'] = 1

both_rects = df.merge(coord_df, key='dummy', suffixes=('_inner', '_outer'))
然后返回到按原始表达式过滤:

rects_within = both_rects.loc[(both_rects.left_inner > both_rects.left_outer) &
                              (both_rects.top_inner > both_rects.left_outer) &
                              (both_rects.left1_inner <= both_rects.left1_outer) &
                              (both_rects.top1_inner <= both_rects.top1_outer)]
rects\u within=both_rects.loc[(both_rects.left\u inner>both_rects.left\u outer)&
(两个右上右内>两个左外)&

(两条直线都是左内我们可以做
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]

比如说

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
你的车熄火了

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

您的数据框/坐标有多长?您可能希望创建坐标的数据框,并使用逐列比较来创建布尔列,然后对布尔列应用&。您将得到一个包含真值或假值的列,可以将其用作索引。Hi@QuangHoang-它有所不同,但坐标列表最多可以是1000,数据框最多可以是2000行。总的来说,每次比较平均需要几秒钟的时间,每次比较大约3msMaybe
np。在这里选择
可能会很有帮助。笔记本电脑远离,所以无法用
timeit
分析发布可靠的答案。我可以知道投票失败的原因吗?你想解释一下我做错的部分吗?嗨@YOBEN,谢谢at的速度明显更快!我已标记为正确。您能帮我解释一下idx one liner以便我更好地理解它是如何工作的吗?@lawson我们将df的每一行与coords进行了比较,在得到子行后,为了匹配输出,我们需要至少有一个子行包含all True,然后如果每一列包含True中的任何一行,我们应该选择它.np.sign,是将负-正和0转换为-1,1,0个hanks,这是有意义的。这不是原始问题的一部分,但我们如何看到哪个坐标元组与相应的数据帧值匹配?
df_sub = df[idx]
print(df_sub)
    left    top1  left1  top
0  10000  100000      0  0.0