移除n维numpy数组的边框

fivyi3re  于 2023-04-12  发布在  其他
关注(0)|答案(3)|浏览(146)

我试图用False替换n维数组边框的所有值。到目前为止,我已经看到numpy提供了np.pad,它允许我用任意数组在所有维度上增长数组。是否有等效的方法来做相反的事情,通过切割边框来“缩小”数组?
下面是一个2D的例子,我想扩展到任意维度:

import numpy as np

nd_array = np.random.randn(100,100)>0   # Just to have a random bool array, but the same would apply with floats, for example

cut_array = nd_array[1:-1, 1:-1]   # This is what I would like to generalize to arbitrary dimension

padded_array = np.pad(cut_array, pad_width=1, mode='constant', constant_values=False)

当然,如果有更容易的方式来改变任意维度的边界的值,那也是可以理解的。

xu3bshqb

xu3bshqb1#

我不会使用先裁剪再填充的方法,因为这样会移动大量内存。
相反,我会显式地将边界索引设置为所需的值:

import numpy as np

nd_array = np.random.randn(100,100) > 0

# Iterate over all dimensions of `nd_array`
for dim in range(nd_array.ndim):
    # Make current dimension the first dimension
    array_moved = np.moveaxis(nd_array, dim, 0)
    # Set border values in the current dimension to False
    array_moved[0] = False
    array_moved[-1] = False
    # We do not even need to move the current dimension
    # back to its original position, as `np.moveaxis()`
    # provides a view into the original data, thus by
    # altering the values of `array_moved`, we also
    # alter the values of `nd_array`. So we are done.

请注意,np.moveaxis()是一个非常便宜的操作,因为它只调整数组的步长(在我们的例子中,是为了生成array_moved),所以实际的数组数据不会被移动。

jucafojl

jucafojl2#

您可以使用np.delete删除最后一列(在您的示例中索引为99)。

import numpy as np

nd_array = np.random.randn(100, 100) > 0

cut_array = np.delete(nd_array, 99, 1) # Delete 100th column (index 99)

padded_array = np.pad(cut_array, pad_width=1, mode='constant', constant_values=False)
yiytaume

yiytaume3#

注意:我认为simon's answer更适合这个特定的问题,但我留下了一个方法来实际删除边框,而不是替换它们,以防有人需要它。
The answer by TheOneMusic通过使用np.delete提出了一个很好的想法,但该答案中的实现并没有为任何维度提供所需的答案。然而,我们可以通过创建一个递归函数来使用这个想法,该函数删除给定轴中的最后一个和第一个元素以及它之前的所有轴:

import numpy as np

def remove_borders(array, last_axis=None):
    if last_axis is None:
        last_axis = len(array.shape)
    new_array = np.delete(array, [0,-1], axis=last_axis)
    if last_axis>0:
        new_array = remove_borders(new_array, last_axis-1)
    return new_array

然后脚本的其余部分看起来像这样:

nd_array = np.random.randn(100,100) > 0   # Just to have a random bool array, but the same would apply with floats, for example

cut_array = remove_borders(nd_array)   

padded_array = np.pad(cut_array, pad_width=1, mode='constant', constant_values=False)

这似乎适用于任意维度,尽管它没有优化,并且可能会与高维的大数组斗争。

相关问题