【问题标题】:Slicing each row in a different way以不同的方式切片每一行
【发布时间】:2021-02-09 21:28:22
【问题描述】:

我有一个numpy.arraya,形状为(8, 16000, 2),代表8 个立体声音频,每个1s 长。我想从每个记录中采样一个 0.5 秒的子样本。因此,我通过以下方式对开始和结束索引进行采样:

a = np.random.rand(8, 16000, 2)
possible_starts = np.arange(8000)
start_idxs = np.random.choice(possible_starts, size=a.shape[0])
end_idxs = start_idxs + 8000

如何在 numpy 高效中为每一行提取这些不同的切片? 我显然可以循环执行:

b = np.zeros((8, 8000, 2))
for i in range(a.shape[0]):
    b[i] = a[i, start_idxs[i]: end_idxs[i], :]

但我想以矢量化的方式进行。

【问题讨论】:

  • 您的示例代码使用ab 而不定义它们
  • @fountainhead 我说它有一个形状 (8, 16000, 2)。它可以是任何这样的 np.array。
  • 如果您提供代码生成示例数据,您将获得更多帮助,以便我们可以复制、粘贴和直接测试代码。这样想:我们想帮忙,但我们也很懒!
  • 那么,每个切片的形状都一样吗?
  • @Divakar 是的,在这种情况下是 8000

标签: python numpy slice numpy-ndarray


【解决方案1】:

我们可以利用基于scikit-image's view_as_windowsnp.lib.stride_tricks.as_strided 来获得滑动窗口视图,从而以矢量化的方式解决我们的问题。

from skimage.util.shape import view_as_windows

w = view_as_windows(a, (1,8000,1))[:,:,:,0,:,0]
b_out = w[np.arange(len(start_idxs)), start_idxs].swapaxes(1,2)

或者按照@Daniel F 的建议使用np.take_along_axis(w, start_idxs, axis=1).swapaxes(1,2) 以获得更好的可读性。

More info on use of as_strided based view_as_windows.

鉴于您的循环仅迭代 8 次,您应该进行基准测试。

【讨论】:

  • b_out = np.take_along_axis(w, start_idxs, 1).swapaxes(1,2) 可能更具可读性?
猜你喜欢
  • 2015-01-19
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 2012-02-01
  • 1970-01-01
相关资源
最近更新 更多