在Python中加速点是否在形状中的顺序检查

在Python中加速点是否在形状中的顺序检查,python,pandas,matplotlib,geometry,vectorization,Python,Pandas,Matplotlib,Geometry,Vectorization,我有一个顺序代码,用于判断在我的数据框中找到的每一对笛卡尔坐标是否落入某些几何封闭区域。但我怀疑它相当慢,因为它没有矢量化。以下是一个例子: from matplotlib.patches import Rectangle r1 = Rectangle((0,0), 10, 10) r2 = Rectangle((50,50), 10, 10) df = pd.DataFrame([[1,2],[-1,5], [51,52]], columns=['x', 'y']) for j in r

我有一个顺序代码,用于判断在我的
数据框中找到的每一对笛卡尔坐标是否落入某些几何封闭区域。但我怀疑它相当慢,因为它没有矢量化。以下是一个例子:

from matplotlib.patches import Rectangle

r1 = Rectangle((0,0), 10, 10)
r2 = Rectangle((50,50), 10, 10)

df = pd.DataFrame([[1,2],[-1,5], [51,52]], columns=['x', 'y'])

for j in range(df.shape[0]):
    coordinates = df.x.iloc[j], df.y.iloc[j]
    if r1.contains_point(coordinates):
        df['location'].iloc[j] = 0
    else r2.contains_point(coordinates):
        df['location'].iloc[j] = 1

有人能提出一种加速方法吗?

最好将矩形面片转换成一个阵列,并在推断出它们的分布范围后再进行处理

def seqcheck_vect(df):
    xy = df[["x", "y"]].values
    e1 = np.asarray(rec1.get_extents())
    e2 = np.asarray(rec2.get_extents())
    r1m1, r1m2 = np.min(e1), np.max(e1)
    r2m1, r2m2 = np.min(e2), np.max(e2)
    out = np.where(((xy >= r1m1) & (xy <= r1m2)).all(axis=1), 0, 
                   np.where(((xy >= r2m1) & (xy <= r2m2)).all(axis=1), 1, np.nan))
    return df.assign(location=out)
在10K行的
DF上测试:


因此,矢量化方法比循环方法快大约2200倍。

谢谢。我想知道,有没有一种更通用的方法不依赖于它是矩形,而是矢量化的?如果我没有弄错的话,您的方法确实依赖于它。基本上,任何具有与
DF
中存在的值进行比较的范围的结构都将遵循如上所示的类似实现。应该有一种方法可以从中提取起始点和结束点,并将结果存储在数组中。此外,所有修补程序都有一个
.get_extents()
方法,因此我想这不会造成任何问题。
def loopy_version(df):
    for j in range(df.shape[0]):
        coordinates = df.x.iloc[j], df.y.iloc[j]
        if rec1.contains_point(coordinates):
            df.loc[j, "location"] = 0
        elif rec2.contains_point(coordinates):
            df.loc[j, "location"] = 1
        else:
            pass
    return df
np.random.seed(42)
df  = pd.DataFrame(np.random.randint(0, 100, (10000,2)), columns=list("xy"))

# check if both give same outcome
loopy_version(df).equals(seqcheck_vect(df))
True

%timeit loopy_version(df)
1 loop, best of 3: 3.8 s per loop

%timeit seqcheck_vect(df)
1000 loops, best of 3: 1.73 ms per loop