【问题标题】:Numpy subarrays and relative indexingNumpy 子数组和相对索引
【发布时间】:2023-01-11 05:12:23
【问题描述】:

我一直在搜索是否有使用相对索引创建子数组的标准方法。考虑以下数组:

>>> m = np.arange(25).reshape([5, 5])
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

我想访问特定数组位置的 3x3 矩阵,例如 [2,2]:

>>> x = 2, y = 2
>>> m[slice(x-1,x+2), slice(y-1,y+2)]
array([[ 6,  7,  8],
       [11, 12, 13],
       [16, 17, 18]])

例如上面的一些东西,比如m.subarray(pos=[2,2], shape=[3,3]) 我想在可能会改变的特定位置上对 n 维的 ndarray 进行采样。

我不想使用循环,因为它可能是无效的。 Scipy 函数correlateconvolve 非常有效地执行此操作,但适用于所有职位。我只对其中一个样本感兴趣。

最好的答案可以解决边缘问题,在我的例子中,我希望有 wrap 模式: (a b c d | a b c d | a b c d)

------------------编辑----------------------------

根据@Carlos Horn 的回答,我可以创建以下函数。

def cell_neighbours(array, index, shape):  
    pads = [(floor(dim/2), ceil(dim / 2)) for dim in shape]
    array = np.pad(self.configuration, pads, "wrap")
    views = np.lib.stride_tricks.sliding_window_view
    return views(array, shape)[tuple(index)]

最后一个问题可能是关于速度,来自docsFor many applications using a sliding window view can be convenient, but potentially very slow. Often specialized solutions exist

从这里可能更容易获得更快的解决方案。

【问题讨论】:

  • 关于速度的评论是指使用这些窗口的聚合,例如滚动平均值可能不需要对所有窗口中的所有值求和,但只能减去窗口外的值并添加进入窗口的值等。在您的情况下,您只想访问给定位置的矩阵。在这里,构建视图不是瓶颈,它是由于复制数据而产生的填充成本,但如果您的阵列不是很大,则可能没什么大不了的。

标签: numpy numpy-ndarray numpy-slicing


【解决方案1】:

您可以将 3x3 矩阵的视图构建到数组中,如下所示:

import numpy as np
m = np.arange(25).reshape(5,5)
m3x3view = np.lib.stride_tricks.sliding_window_view(m, (3,3))

请注意,它会略微改变您在一半窗口大小上的索引,这意味着

x_view = x - 3//2
y_view = y - 3//2
print(m3x3view[x_view,y_view])  # gives your result

如果复制操作没问题,您可以使用:

mpad = np.pad(m, 1, mode="wrap")
mpad3x3view = np.lib.stride_tricks.sliding_window_view(mpad, (3,3))
print(mpad3x3view[x % 5,y % 5])

使用任意 x, y 整数值。

【讨论】:

  • 这是一个很好的方法,但现在我正在测试,我可能在数组的角落有问题。
  • 您可以在创建数组视图之前使用np.pad。请注意,这将创建初始矩阵的副本。查看答案的编辑。
猜你喜欢
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 2021-12-01
  • 2015-10-31
  • 2021-04-22
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多