【问题标题】:Extract hyper-cubical blocks from a numpy array with unknown number of dimensions从维数未知的 numpy 数组中提取超立方块
【发布时间】:2016-09-05 13:08:55
【问题描述】:

我有一些 Python 代码,目前与二维数组硬连线如下:

import numpy as np
data = np.random.rand(5, 5)
width = 3

for y in range(0, data.shape[1] - W + 1):
    for x in range(0, data.shape[0] - W + 1):
        block = data[x:x+W, y:y+W]
        # Do something with this block

现在,这是为二维数组硬编码的,我想将其扩展到 3D 和 4D 数组。当然,我可以为其他维度编写更多函数,但我想知道是否有 python/numpy 技巧来生成这些子块,而不必为多维数据复制此函数。

【问题讨论】:

  • ndim 会给你维度的数量。如果你构造你的代码来迭代range(arr.ndim),那么你将重复你正在为数组中的维数所做的任何事情
  • @Andrew 感谢您的评论。问题是我无法弄清楚如何构建这些也将具有ndim 尺寸的块。既然我写了这个,也许列表理解可能是一种方法......
  • 我通常会发现,如果我在迭代 numpy 数组,几乎总有一个更好的解决方案可以更有效地使用 numpy
  • 是的,在这里尽我所能。如果我破解它,我会更新:)
  • 看起来您有一个 5x5 数组,并且您正在收集其中的所有 3x3 数组。您是否在问:如果您有一个 5x5x5,如何收集所有 3x3x3 阵列?或者:如何为 5 层中的每一层收集所有 3x3?换句话说,收集的数据是否应该与输入数据具有相同的维度?

标签: python numpy multidimensional-array


【解决方案1】:

这是我对这个问题的看法。下面代码背后的想法是找到每个数据片的“起始索引”。因此,对于 5x5x5 数组的 4x4x4 子数组,起始索引为 (0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,1),沿每个维度的切片长度为 4。

要获取子数组,您只需要遍历切片对象的不同元组并将它们传递给数组。

import numpy as np
from itertools import product

def iterslice(data_shape, width):
    # check for invalid width
    assert(all(sh>=width for sh in data_shape), 
           'all axes lengths must be at least equal to width')

    # gather all allowed starting indices for the data shape
    start_indices = [range(sh-width+1) for sh in data_shape]

    # create tuples of all allowed starting indices
    start_coords = product(*start_indices)

    # iterate over tuples of slice objects that have the same dimension
    # as data_shape, to be passed to the vector
    for start_coord in start_coords:
        yield tuple(slice(coord, coord+width) for coord in start_coord)

# create 5x5x5 array
arr = np.arange(0,5**3).reshape(5,5,5)

# create the data slice tuple iterator for 3x3x3 sub-arrays
data_slices = iterslice(arr.shape, 3)

# the sub-arrays are a list of 3x3x3 arrays, in this case
sub_arrays = [arr[ds] for ds in data_slices]

【讨论】:

  • 谢谢!我想我找到了一个与您的非常相似的解决方案,但无法让它真正发挥作用。特别是,不知道slice函数存在!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多