凸包中的点并将 True/False 分配给数据框

Points in convex hull and assign True/False to the dataframe

这是我的起点,我有以下两个点数据集

data1 = {'x': [580992.9581, 580992.9111, 580993.3539, 580993.4957, 580991.9780],
         'y': [4275268.7194, 4275267.6678, 4275267.2215, 4275268.1749, 4275267.6297]}

df1 = pd.DataFrame(data1)

data2 = {'x': [580992.7155, 580993.4258, 580992.7421, 580991.7034, 580992.7554, 580993.5837, 580993.0002, 580993.8348, 580991.2176, 580992.0536],
         'y': [4275267.2733, 4275267.7455, 4275266.7449, 4275268.8644, 4275266.4493, 4275267.5785, 4275268.5525, 4275268.9687, 4275267.6972, 4275267.7937]}

df2 = pd.DataFrame(data2)

我想以最有效的方式计算每个数据帧的凸包,然后确定哪些点在另一个数据帧的凸包中。

因此创建 hull_of_df1hull_of_df2

要使用 Scipy 的“ConvexHull(df1)”或在 Shapely 中执行此操作,我们使用 scipy.

from scipy.spatial import ConvexHull
hull_of_df1 = ConvexHull(df1)
hull_of_df2 = ConvexHull(df2)

现在,我需要将 True 分配给 df1hull_of_df2 中的任何点。

要做到这一点,很长的路要走:

for point in df1:
    if point.within(hull_of_df2):
        df1['in_hull'] = True
    else:
        df1['in_hull'] = False

并重复其他数据框和其他凸包。

理想情况下,我只想生成一个新列并将其附加到 df1 数据框的末尾。因此,对于 df1 内的那些索引,分配 in_hull == True。我不想删除数据框中的任何点,只记录哪些点在对面的凸包中,哪些不在。

您可以使用船体方程确定点是否在船体内部

def in_hull(points, hull):
    A = hull.equations
    dist = np.array(points[['x', 'y']]) @ A[:,:2].T + A[:,2]
    return np.all(dist < 0, axis=1)

df1['within'] = in_hull(df1, hull_of_df2);
df2['within'] = in_hull(df2, hull_of_df1);

加上一些情节更有说服力

plt.plot(df1['x'], df1['y'], '.r')
for r in hull_of_df1.simplices:
    plt.plot(df1['x'][r], df1['y'][r], '-r')
plt.plot(df2['x'], df2['y'], '.g')
for r in hull_of_df2.simplices:
    plt.plot(df2['x'][r], df2['y'][r], '-g')

df1['within'] = in_hull(df1, hull_of_df2);
mr = df1['within']
plt.plot(df1['x'][mr], df1['y'][mr], 'xg')

df2['within'] = in_hull(df2, hull_of_df1);
mr = df2['within']
plt.plot(df2['x'][mr], df2['y'][mr], 'xr')