我正在努力使这段代码正常工作我想迭代一个numpy数组,并根据结果,索引到另一个numpy数组中的一个值,然后基于该值将其保存到一个新的位置。在
# Convert the sediment transport and the flow direction rasters into Numpy arrays
sediment_transport_np = arcpy.RasterToNumPyArray(sediment_transport_convert, '#', '#', '#', -9999)
flow_direction_np = arcpy.RasterToNumPyArray(flow_direction_convert, '#', '#', '#', -9999)
[rows,cols]= sediment_transport_np.shape
elevation_change = np.zeros((rows,cols), np.float)
# Main body for calculating elevation change
# Attempt 1
for [i, j], flow in np.ndenumerate(flow_direction_np):
if flow == 32:
elevation_change[i, j] = sediment_transport_np[i - 1, j - 1]
elif flow == 16:
elevation_change[i, j] = sediment_transport_np[i, j - 1]
elif flow == 8:
elevation_change[i, j] = sediment_transport_np[i + 1, j - 1]
elif flow == 4:
elevation_change[i, j] = sediment_transport_np[i + 1, j]
elif flow == 64:
elevation_change[i, j] = sediment_transport_np[i - 1, j]
elif flow == 128:
elevation_change[i, j] = sediment_transport_np[i - 1, j + 1]
elif flow == 1:
elevation_change[i, j] = sediment_transport_np[i, j + 1]
elif flow == 2:
elevation_change[i, j] = sediment_transport_np[i + 1, j + 1]
我得到的错误是:
正在运行脚本提升更改。。。在
回溯(最近一次调用):文件“”,第606行,在执行索引器错误:索引(655)超出范围(0<;=索引<;655)在维度0中
执行失败(提升更改)
问题的原因
错误是因为您试图索引到
sediment_transport
网格的边界之外(例如i+1和j+1部分)。现在,你试图得到一个当你在网格边界时不存在的值。而且,它不会引发错误,但是当你在i=0或j=0时,你正在抓取相反的边(由于i-1和j-1部分)。在您提到您希望
elevation_change
的值在边界处为0(这显然是合理的)。另一个常见的边界条件是“包装”这些值并从另一个边获取一个值。在本例中,这可能没有多大意义,但我将在几个示例中展示它,因为使用某些方法很容易实现。在诱人但不正确
很容易捕捉到异常并将值设置为0。例如:
然而,这种方法实际上是不正确的。负索引有效,将返回网格的相对边。因此,这将基本上在网格的右边缘和下边缘实现“零”边界条件,在左侧和顶部边缘实现“环绕”边界条件。在
用零填充
在“零”边界条件的情况下,有一种非常简单的方法来避免索引问题:用零填充
sediment_transport
网格。这样,如果索引超出原始网格的边缘,我们将得到0。(或任何您想填充数组的常量值。)旁注:这是使用
numpy.pad
的完美地方。但是,它是在v1.7中添加的。我将在这里跳过使用它,因为OP提到了ArcGIS,Arc并没有提供最新版本的numpy。例如:
^{2}$干(不要重复)
我们可以使用
dict
来编写这段代码:此时,填充原始数组有点多余。如果使用
numpy.pad
,通过填充实现不同的边界条件非常容易,但我们可以直接写出逻辑:“矢量化”计算
在python中迭代numpy数组是相当缓慢的,原因是我将不在这里深入研究。因此,在numpy中有更有效的方法来实现这一点。诀窍是将
numpy.roll
与布尔索引一起使用。在对于“环绕”边界条件,它很简单:
如果你不熟悉numpy,这可能看起来有点像希腊语。这有两个部分。第一种是使用布尔索引。作为一个简单的例子:
如您所见,如果我们用相同形状的布尔网格索引数组,则返回其为真的值。类似地,您可以这样设置值。在
下一个技巧是
numpy.roll
。这将使值在一个方向上移动给定的量。它们会在边缘“缠绕”。在希望这有点道理,无论如何。在
要实现“零”边界条件(或使用
numpy.pad
的任意边界条件),我们可以这样做:矢量化的优势
“矢量化”版本速度更快,但将使用更多的RAM。在
对于1000 x 1000网格:
这些结果是通过将以下实现与随机生成的数据进行比较得出的:
相关问题 更多 >
编程相关推荐