使用Python有效查找每个像素中的点

时间:2019-01-10 19:59:53

标签: python numpy

我有一个表示一组像素的2D网格。对于每个像素,我都有左上角的坐标。

我还有很长的随机分布的2D点列表。我正在寻找一种找到每个像素中存在的点的索引的有效方法。

目前,我有以下内容:

import numpy as np
xgrid = np.linspace(0,10,11)
ygrid = np.linspace(0,10,11)

X_random_points = np.random.rand(int(1e7))*10
Y_random_points = np.random.rand(int(1e7))*10

for iterationX in range(0,len(xgrid)-1):
    for iterationY in range(0,len(ygrid)-1):
        valuesInCube = (X_random_points<xgrid[iterationX]) & (X_random_points>xgrid[iterationX-1]) & (Y_random_points<ygrid[iterationY]) &(Y_random_points>ygrid[iterationY-1])  

我在想,是否有人对如何更快地实现这一想法?

2 个答案:

答案 0 :(得分:1)

您可以使用np.floor对整个操作进行矢量化处理,并避免完全循环,只要在每个方向上像素之间的间距均匀即可。对于简单的情况,xgridygrid是整数,您可以这样做

X_random_points = ...
Y_random_points = ...
x_pixels = np.floor(X_random_points)
y_pixels = np.floor(Y_random_points)

如果像素不在整数网格上,则必须知道它们之间的间隔。在这种情况下,我建议使用np.arange而不是np.linspace来生成像素位置:

delta_x, delta_y = 0.5, 0.5
xgrid = np.arange(0, 5.1, delta_x)
ygrid = np.arange(0, 5.1, delta_y)

X_random_points = np.random.rand(int(1e7)) * 5
Y_random_points = np.random.rand(int(1e7)) * 5

x_pixels = np.floor(X_random_points / delta_x)
y_pixels = np.floor(Y_random_points / delta_y)

对于整数情况,您实际上是在做同样的事情,因为delta_xdelta_y都是1

答案 1 :(得分:1)

我可以为您提供可能仍然有用的相关方法。您可以找到每个点属于哪个像素。函数numpy.digitizescipy.stats.binned_statistic_2d在这里很有用。 scipy.stats.binned_statistic_2d有点笨拙,因为它不仅可以对点进行分箱,还需要为每个x,y点提供一些值。

您应注意,bin编号从1(而不是0)开始计数。

x_p, y_p = np.digitize(X_random_points, xgrid), np.digitize(Y_random_points, xgrid)

# OR #

_, _, _, (x_p, y_p) = scipy.stats.binned_statistic_2d(X_random_points, Y_random_points, np.zeros(len(X_random_points)), bins=(xgrid, ygrid), expand_binnumbers=True)

对于特定像素,您甚至可以从x_py_p中找到属于该像素的所有点。