首页 > 解决方案 > 用特定轴旁边的中值填充 3 维 numpy 数组

问题描述

假设我有以下 numpy 数组 arr:

[[[  0   0]
  [  1  10]
  [  2  20]]

 [[  3  30]
  [  4  40]
  [  5  50]]

 [[  6  60]
  [  7  70]
  [  8  80]]

 [[  9  90]
  [ 10 100]
  [ 11 110]]

 [[ 12 120]
  [ 13 130]
  [ 14 140]]]

有形状(5, 3, 2)

现在,请注意 arr 的以下维度:

第一个`arr [:, :, 0]

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
 [12 13 14]]

有中位数7

和 `arr[:, :, 1]

[[  0  10  20]
 [ 30  40  50]
 [ 60  70  80]
 [ 90 100 110]
 [120 130 140]]

中位数 70

我想用上面的一对中位数填充第一个轴(可以arr计算为np.median(a.reshape(-1, a.shape[-1]), axis=0)(k, 3, 2)k=2(7, 3, 2)

[[[  0   0]
  [  1  10]
  [  2  20]]

 [[  3  30]
  [  4  40]
  [  5  50]]

 [[  6  60]
  [  7  70]
  [  8  80]]

 [[  9  90]
  [ 10 100]
  [ 11 110]]

 [[ 12 120]
  [ 13 130]
  [ 14 140]]

 [[ 7 70]
  [ 7 70]
  [ 7 70]]

 [[ 7 70]
  [ 7 70]
  [ 7 70]]]

请注意,我不能使用 的mode='median'参数numpy.pad,因为它无法计算仅考虑数组的一个轴并展平其他轴的中位数(如果我修复某个轴,它将始终计算其他每个轴上的单个中位数)。

问题是,我曾经能够在 numpy 2.16 中以非常简单的方式做到这一点:

md = np.median(a.reshape(-1, a.shape[-1]), axis=0)
arp = np.pad(a, ((0, k), (0, 0), (0, 0)), mode='constant', constant_values=(0, md))

但相同的代码在 numpy 2.19 中中断,出现以下错误:

ValueError: could not broadcast input array from shape (2) into shape (7,3,0)

使用numpy.pad,我尝试了很多输入变化,但没有运气。老实说,这让我发疯,在这一点上,我几乎只是简单地堆叠中位数数组的重复。但我真的很想知道是否可以在 numpy 2.19 中使用numpy.pad

标签: pythonarraysnumpypadding

解决方案


How about:

# (reproducible setup)
a = np.arange(15).reshape(5,3,1)
a = np.concatenate((a, a*10), axis=-1)

# median along axes 0,1
md = np.median(a, axis=(0,1))

# "padding" with that median
k = 2
b = np.vstack((a, np.tile(md, (k, a.shape[1], 1))))
>>> b
array([[[  0.,   0.],
        [  1.,  10.],
        [  2.,  20.]],

       [[  3.,  30.],
        [  4.,  40.],
        [  5.,  50.]],

       [[  6.,  60.],
        [  7.,  70.],
        [  8.,  80.]],

       [[  9.,  90.],
        [ 10., 100.],
        [ 11., 110.]],

       [[ 12., 120.],
        [ 13., 130.],
        [ 14., 140.]],

       [[  7.,  70.],
        [  7.,  70.],
        [  7.,  70.]],

       [[  7.,  70.],
        [  7.,  70.],
        [  7.,  70.]]])

Edit: If you want to use pad, then you can also do this:

b = np.pad(
    a.reshape((-1, 2)),
    ((0,k*a.shape[1]), (0,0)),
    mode='median',
).reshape(np.add(a.shape, (k,0,0)))

That lets you use the mode='median' that you were looking for, in a way that is natural for pad().


推荐阅读