首页 > 解决方案 > 根据第二个数组中的值翻转 numpy 数组轴

问题描述

目前正在为 Keras 编写一个自定义数据生成器,我希望在训练期间随机翻转一个 numpy 输入数组以进行数据增强。

例如:

X = [[[0, 1],
      [2, 3]],
     [[4, 5],
      [6, 7]]]

to_flip = [[0, 1],
           [1, 0]]

flipped_X = [[[1, 0],
              [3, 2]],
             [[6, 7],
              [4, 5]]]

或轴的任何组合(两个/没有轴翻转)。我无法弄清楚如何自己使用任何一个np.flip或高级索引(例如X[::-1])来获得这种效果。理想情况下,我能够找到一个无需显式循环即可应用于整个批次的解决方案,因为我相信这样的解决方案会更快。

我目前最好的解决方案是:

def flip_axes(an_input, axes_to_flip):
    axis_inds_to_flip = np.where(axes_to_flip.reshape(-1))[0]
    return np.flip(an_input, axis_inds_to_flip)[None, ...]

flipped_X = np.concatenate([flip_axes(an_input, axes_to_flip) 
                            for an_input, axes_to_flip 
                            in zip(X, to_flip)], axis=0)

有人有什么想法吗?这真的会比我在这里写的更快吗?

编辑:我已经修改了我的解决方案以便它可以执行,并且我已经添加了我对这个问题的动机。

标签: pythonarraysnumpykerasflip

解决方案


你可以使用python索引来做到这一点,如下所示,

flipped_X = []
for sample, flip in zip(X, to_flip):
  flipped = [*sample]                          # Generate a copy of x
  if flip[0]:                                  # if flip[0] is 1
    flipped = flipped[::-1]                    # Flip matrix vertically
  if flip[1]:                                  # if flip[1] is 1
    flipped = [elem[::-1] for elem in flipped] # Flip elements to flip horizontally
  flipped_X.append(flipX)                      # Finally append to result
print(flipped_X)

将输出:

[[[1, 0], [3, 2]], [[6, 7], [4, 5]]]

编辑:使用 numpy 你可以得到相同的结果,每个矩阵在np.flip(m, axis)哪里,并且是一个要翻转的索引的元组。例如:mXaxis

to_flip = [[0,0], [1,0], [0,1], [1,1]]

所以索引将是

[[], [0], [1], [0,1]]

# Get indexes to flip at each sample
flip_idxes = map(lambda flip: [idx for idx, x in enumerate(flip) if x], to_flip)
# Flip samples
flipped_X = np.array([np.flip(sample, indexes) for sample, indexes in zip(X, flip_idxes)])

推荐阅读