【问题标题】:Selecting random windows from numpy arrays greater than 2 dimensions从大于 2 维的 numpy 数组中选择随机窗口
【发布时间】:2020-02-23 10:17:24
【问题描述】:

如何从大于 2 个维度的 numpy 数组中选择一个随机窗口,其中窗口相对于 2 个不同维度是随机的?

我想做一些与这篇文章中的答案类似的事情,但是是 3 个维度,而不是 2 个维度: Selecting Random Windows from Multidimensional Numpy Array Rows

我试图矢量化的示例(即我试图避免 for 循环):

import random
import numpy as np

ls = []
m = 3 # sequence length
k = 8 #batch_size

np_3D_array = np.random.randint(0,100, size = (5,7,4)) #random 3D array

for ii in range(k):
  random_sheet = random.randint(0,np_3D_array.shape[0] - 1)
  random_row = random.randint(0, np_3D_array.shape[1] - m)
  ls.append(np_3D_array[random_sheet, random_row:random_row + m , :])

final_output = np.array(ls)

print(final_output.shape) #prints (8, 3, 4) to stdoout

【问题讨论】:

  • 请在你的问题更清楚。
  • 发布的解决方案是否解决了您的问题?
  • 我仍在实施/测试它们。我会告诉你的,谢谢!

标签: python arrays numpy vectorization


【解决方案1】:

我们可以利用基于np.lib.stride_tricks.as_stridedscikit-image's view_as_windows 来获得滑动窗口。 More info on use of as_strided based view_as_windows.

from skimage.util.shape import view_as_windows

w = view_as_windows(np_3D_array,(1,m,1))[...,0,:,0]
r1 = np.random.randint(0,np_3D_array.shape[0], k)
r2 = np.random.randint(0, np_3D_array.shape[1] - m + 1, k)
final_output = w[r1,r2].swapaxes(1,2)

这里,view_as_windows 是一个方便的函数,它可以帮助我们轻松设置滑动窗口,而不用乱设置as_strided 函数。

【讨论】:

  • 我相信 r1 和 r2 应该是这些,因为 random.randint 包含较大的数字,而 np.random.randint 是排除的(如果我正确理解您的解决方案?): r1 = np.random .randint(0,np_3D_array.shape[0], k) r2 = np.random.randint(0, np_3D_array.shape[1] - m + 1, k)
  • @teter123f 我的错,我认为random.randintnp.random.randint 相同,但前者使用第二个参数作为包容性。帖子已编辑。请检查一下。
  • 嗯,我在尝试这个解决方案时遇到了这个错误(idk,如果我的输入 np_3D_array 有问题。我制作 np_3D_array 的方法是读取形状为 axb 的 csv 文件并将每个文件附加到列出并调用 np.array(the list) 来创建 acxaxb ndarray.... "/usr/local/lib/python3.6/dist-packages/skimage/util/shape.py:246: RuntimeWarning: 无法提供关于不复制的非连续输入数组。warn(RuntimeWarning("Cannot provide views on a non-contiguous input"
  • @teter123f 要使此解决方案起作用,输入必须是连续的,而您的输入似乎并非如此。因此,在不知道您的输入来源的情况下绕过的一种方法是复制np_3D_array,然后使用它。因此,请使用ar = np_3D_array.copy() 之类的内容,然后在发布的代码中使用ar 代替np_3D_array
  • 当我使用 np_3D_array.copy() 时,我仍然得到非连续错误。通过使用 np.ascontiguousarray(np_3D_array),我能够摆脱错误。但是,对于我的特定用例,此解决方案实际上似乎更慢。我需要研究为什么这种矢量化格式 - 具有讽刺意味的是 - 速度较慢。 (我的 np_3D_array 大约是 150 x 50000 x 10 和 k - 即 for 循环传递的数量 - 大约是 3000 所以......非常困惑为什么它更慢)
【解决方案2】:

使用我来自herewindow_nd 食谱

def sample_nd(arr, window_shape, axis, k = 1):
    windows = window_nd(arr, window = window_shape, axis = axis)
    windows = windows.reshape((-1,) + windows.shape[len(axis):])
    index = np.random.randint(0, windows.shape[0], k)
    return windows[index].squeeze()

sample_nd(np_3D_array, window_shape = (1, 3), axis = (0, 1), k = 8).shape

(8, 3, 4)

为了清楚起见,这里没有考虑原始函数中的很多边缘情况(尤其是不能仅使用一个窗口/轴,除非它们被格式化为元组)。

【讨论】:

    猜你喜欢
    • 2018-06-07
    • 2017-09-16
    • 2021-08-16
    • 2018-11-11
    • 2014-04-21
    • 2014-05-15
    • 2017-09-16
    相关资源
    最近更新 更多