移除n维numpy数组的边框



我试图用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)

当然,如果有一种更简单的方法来改变任意维度的边界值,那也将是值得赞赏的。

我不会使用先裁剪后填充的方法,因为这样会移动大量内存。

相反,我会显式地将边框索引设置为所需的值:
import numpy as np
border_value = False
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
array_moved[0] = border_value
array_moved[-1] = border_value
# 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),所以没有实际的数组数据被移动。

注意:我认为simon的答案对于这个特定的问题更好,但是我留下了一个方法来实际删除边界而不是替换它们,以防有人需要它。


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)

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

您可以使用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)

最新更新