【发布时间】:2020-11-01 16:58:34
【问题描述】:
Python GIS 开发人员的问题。我有一个高密度的 3D 点云,每个像素最多有 73 个观测值。云是用 SFM 获得的。我正在将云中的 DEM 融合为 HSI 图像中的新波段,以供将来分析。
我有一个代表 8 个波段(n 点、min z、maz z、sum z...)的 numpy 数组。我需要根据点云更改此数组的值。因此,我一次只能处理一个像素,这使得 numpy 向量化成为一个坏主意。
变量是: map_z = 平均海平面以上单个云点高度的浮点数数组是 8 波段 numpy 数组
array = np.full((nbands, 2000, 3000), np.nan, dtype=OUTPUT_RASTER_DTYPE)
我已经尝试了两个版本的代码。矢量化版本和 Else If 版本。
slice_arr = array[0:4, pixel_y, pixel_x]
slice_arr[0] = np.where(slice_arr[0] == 0, 1, slice_arr[0] + 1)
slice_arr[1] = np.select([np.isnan(slice_arr[1]) == True, slice_arr[1] > map_z], [map_z, map_z], slice_arr[1])
slice_arr[2] = np.select([np.isnan(slice_arr[2]) == True, slice_arr[2] < map_z], [map_z, map_z], slice_arr[2])
slice_arr[3] = np.where(np.isnan(slice_arr[3]) == True, map_z, slice_arr[3] + map_z)
array[0:4, pixel_y, pixel_x] = slice_arr
或
slice_arr = array[0:4, pixel_y, pixel_x] # Take a slice of the array
if slice_arr[0] == 0:
slice_arr[0] = 1
else:
slice_arr[0] = slice_arr[0] + 1
if np.isnan(slice_arr[1]) == True:
slice_arr[1] = map_z
elif slice_arr[1] > map_z:
slice_arr[1] = map_z
else:
pass
if np.isnan(slice_arr[2]) == True:
slice_arr[2] = map_z
elif slice_arr[2] < map_z:
slice_arr[2] = map_z
else:
pass
if np.isnan(slice_arr[3]) == True:
slice_arr[3] = map_z
else:
slice_arr[3] = slice_arr[3] + map_z
array[0:4, pixel_y, pixel_x] = slice_arr
显然,If else 版本快 4 倍,因为我一次操作一个像素。这是因为 map_z 是一个点云,我一次只能处理一个点,而这些点只落在我数组中的一个像素上。向量化应该在更大的数组上进行。
有没有一种方法可以使用 numpy 加快这部分代码的速度? 如果数组比 (8,2000,3000) 大得多,对数组 (slice_arr) 进行切片有速度优势吗?
【问题讨论】:
-
如果您一次只查看一个像素,那么您使用 numpy 的所有花哨机制就是在浪费时间。它们旨在为您提供矢量化操作的加速。因此,如果您真的一次需要一个像素,那么无论如何,第二个。如果你可以向量化操作(摆脱pixel_x,pixel_y),那么使用第一个。
-
好的,谢谢,我对代码的下一部分进行矢量化以计算出平均值和一些掩码,我会很快的。我希望有一种方法可以使用 np.where() ,其中每个条件都可以应用于我的切片的一部分。感谢您的意见。
标签: python numpy gis array-broadcasting