gpt4 book ai didi

python - 将 numpy 点数组分配给二维方形网格

转载 作者:太空宇宙 更新时间:2023-11-03 13:41:27 26 4
gpt4 key购买 nike

我要超越 my上一个问题因为速度问题。我有一个点的纬度/经度坐标数组,我想将它们分配给一个索引代码,该索引代码从具有相同大小单元格的二维正方形网格派生。这是一个例子。让我们将第一个包含六个点的坐标(称为 [x y] 对)的数组称为 points:

points = [[ 1.5  1.5]
[ 1.1 1.1]
[ 2.2 2.2]
[ 1.3 1.3]
[ 3.4 1.4]
[ 2. 1.5]]

然后我有另一个数组,其中包含 [minx,miny,maxx,maxy] 形式的两个单元格的网格的顶点坐标;我们称它为 bounds:

bounds = [[ 0.  0.  2.  2.]
[ 2. 2. 3. 3.]]

我想找到哪些点在哪个边界,然后分配一个从 bounds 数组索引派生的代码(在这种情况下,第一个单元格的代码为 0,第二个单元格的代码为 1,依此类推...)。由于单元格是正方形,计算每个点是否在每个单元格中的最简单方法是评估:

x > minx & x < maxx & y > miny & y < maxy

这样生成的数组将显示为:

results = [0 0 1 0 NaN NaN]

其中 NaN 表示该点在单元格外。在我的真实案例中,元素的数量是在 10^4 个单元格中找到 10^6 个点的顺序。有没有一种方法可以使用 numpy 数组快速完成此类操作?

编辑:澄清一下,results 数组预期意味着第一个点在第一个单元格内(bounds 数组的 0 索引),所以第二个和第一个位于 bounds 数组的第二个单元格内,依此类推...

最佳答案

这是解决您的问题的矢量化方法。它应该会显着加快速度。

import numpy as np
def findCells(points, bounds):
# make sure points is n by 2 (pool.map might send us 1D arrays)
points = points.reshape((-1,2))

# check for each point if all coordinates are in bounds
# dimension 0 is bound
# dimension 1 is is point
allInBounds = (points[:,0] > bounds[:,None,0])
allInBounds &= (points[:,1] > bounds[:,None,1])
allInBounds &= (points[:,0] < bounds[:,None,2])
allInBounds &= (points[:,1] < bounds[:,None,3])


# now find out the positions of all nonzero (i.e. true) values
# nz[0] contains the indices along dim 0 (bound)
# nz[1] contains the indices along dim 1 (point)
nz = np.nonzero(allInBounds)

# initialize the result with all nan
r = np.full(points.shape[0], np.nan)
# now use nz[1] to index point position and nz[0] to tell which cell the
# point belongs to
r[nz[1]] = nz[0]
return r

def findCellsParallel(points, bounds, chunksize=100):
import multiprocessing as mp
from functools import partial

func = partial(findCells, bounds=bounds)

# using python3 you could also do 'with mp.Pool() as p:'
p = mp.Pool()
try:
return np.hstack(p.map(func, points, chunksize))
finally:
p.close()

def main():
nPoints = 1e6
nBounds = 1e4

# points = np.array([[ 1.5, 1.5],
# [ 1.1, 1.1],
# [ 2.2, 2.2],
# [ 1.3, 1.3],
# [ 3.4, 1.4],
# [ 2. , 1.5]])

points = np.random.random([nPoints, 2])

# bounds = np.array([[0,0,2,2],
# [2,2,3,3]])

# bounds = np.array([[0,0,1.4,1.4],
# [1.4,1.4,2,2],
# [2,2,3,3]])

bounds = np.sort(np.random.random([nBounds, 2, 2]), 1).reshape(nBounds, 4)

r = findCellsParallel(points, bounds)
print(points[:10])
for bIdx in np.unique(r[:10]):
if np.isnan(bIdx):
continue
print("{}: {}".format(bIdx, bounds[bIdx]))
print(r[:10])

if __name__ == "__main__":
main()

编辑:
用你的数据量尝试它给了我一个 MemoryError。如果您使用 multiprocessing.Pool 及其 map 函数,您可以避免这种情况,甚至可以加快速度,请参阅更新的代码。

结果:

>time python test.py
[[ 0.69083585 0.19840985]
[ 0.31732711 0.80462512]
[ 0.30542996 0.08569184]
[ 0.72582609 0.46687164]
[ 0.50534322 0.35530554]
[ 0.93581095 0.36375539]
[ 0.66226118 0.62573407]
[ 0.08941219 0.05944215]
[ 0.43015872 0.95306899]
[ 0.43171644 0.74393729]]
9935.0: [ 0.31584562 0.18404152 0.98215445 0.83625487]
9963.0: [ 0.00526106 0.017255 0.33177741 0.9894455 ]
9989.0: [ 0.17328876 0.08181912 0.33170444 0.23493507]
9992.0: [ 0.34548987 0.15906761 0.92277442 0.9972481 ]
9993.0: [ 0.12448765 0.5404578 0.33981119 0.906822 ]
9996.0: [ 0.41198261 0.50958195 0.62843379 0.82677092]
9999.0: [ 0.437169 0.17833114 0.91096133 0.70713434]
[ 9999. 9993. 9989. 9999. 9999. 9935. 9999. 9963. 9992. 9996.]

real 0m 24.352s
user 3m 4.919s
sys 0m 1.464s

关于python - 将 numpy 点数组分配给二维方形网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30481577/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com