python - 根据第二个数组中的值翻转 numpy 数组轴
问题描述
目前正在为 Keras 编写一个自定义数据生成器,我希望在训练期间随机翻转一个 numpy 输入数组以进行数据增强。
X
: 形状的输入数组(batchsize, y_dim, x_dim)
to_flip
:布尔形状数组(batchsize, X_rank)
,描述要翻转的轴
例如:
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)
有人有什么想法吗?这真的会比我在这里写的更快吗?
编辑:我已经修改了我的解决方案以便它可以执行,并且我已经添加了我对这个问题的动机。
解决方案
你可以使用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)
哪里,并且是一个要翻转的索引的元组。例如:m
X
axis
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)])
推荐阅读
- javascript - 在这种情况下,我们必须使用这些 Object 字面量、构造函数和 Object.create() 之一,它们之间有何不同?
- php - 使用 php 将 jason 文件发布到 api?
- angular - 未从前端调用补丁 API 调用
- python - 使用 pandas 数据框列中的值更改 DateTime 对象的日期
- rust - 如何在使用 actix-web 代理流式传输大文件时防止超时问题?
- java - .jar UI 在 Linux redhat/centos 7.X 中不起作用
- html - 使用 :not CSS 选择器
- macos - 安装 gnuplot 时 Homebrew/brew 没有选择选项
- android - 没有“clean”或“--rerun-tasks”选项,Gradle 不会运行测试
- javascript - 为什么 Material-UI 无法识别 theme.spacing 功能?