简体   繁体   English

基于二维 arrays 的 3D numpy 切片的平均值

[英]Average of a 3D numpy slice based on 2D arrays

I am trying to calculate the average of a 3D array between two indices on the 1st axis.我正在尝试计算第一个轴上两个索引之间的 3D 数组的平均值。 The start and end indices vary from cell to cell and are represented by two separate 2D arrays that are the same shape as a slice of the 3D array.开始和结束索引因单元格而异,由两个单独的 2D arrays 表示,它们的形状与 3D 阵列的切片相同。

I have managed to implement a piece of code that loops through the pixels of my 3D array, but this method is painfully slow in the case of my array with a shape of (70, 550, 350) .我已经设法实现了一段代码,它循环遍历我的 3D 数组的像素,但是对于形状为(70, 550, 350)的数组,这种方法非常缓慢。 Is there a way to vectorise the operation using numpy or xarray (the arrays are stored in an xarray dataset)?有没有办法使用numpyxarray对操作进行矢量化(arrays 存储在xarray数据集中)?

Here is a snippet of what I would like to optimise:这是我想要优化的片段:

# My 3D raster containing values; shape = (time, x, y)
values = np.random.rand(10, 55, 60)

# A 2D raster containing start indices for the averaging
start_index = np.random.randint(0, 4, size=(values.shape[1], values.shape[2]))

# A 2D raster containing end indices for the averaging
end_index = np.random.randint(5, 9, size=(values.shape[1], values.shape[2]))

# Initialise an array that will contain results
mean_array = np.zeros_like(values[0, :, :])

# Loop over 3D raster to calculate the average between indices on axis 0
for i in range(0, values.shape[1]):
    for j in range(0, values.shape[2]):
        mean_array[i, j] = np.mean(values[start_index[i, j]: end_index[i, j], i, j], axis=0)

One way to do this without loops is to zero-out the entries you don't want to use, compute the sum of the remaining items, then divide by the number of nonzero entries.在没有循环的情况下执行此操作的一种方法是将您不想使用的条目清零,计算剩余项目的总和,然后除以非零条目的数量。 For example:例如:

i = np.arange(values.shape[0])[:, None, None]
mean_array_2 = np.where((i >= start_index) & (i < end_index), values, 0).sum(0) / (end_index - start_index)
np.allclose(mean_array, mean_array_2)
# True

Note that this assumes that the indices are in the range 0 <= i < values.shape[0] ;请注意,这假设索引在0 <= i < values.shape[0]范围内; if this is not the case you can use np.clip or other means to standardize the indices before computation.如果不是这种情况,您可以使用np.clip或其他方法在计算之前标准化索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM