【问题标题】:Sampling a fixed length sequence from a numpy array从 numpy 数组中采样固定长度的序列
【发布时间】:2021-03-23 13:26:49
【问题描述】:

我有一个数据矩阵a,并且我有存储在数组idx 中的索引列表。我想从 idx 定义的每个索引开始获取 10 长度的数据。现在我使用for 循环来实现这一点。但它非常慢,因为我必须在一次迭代中获取大约 1000 次数据。下面是一个最小的工作示例。

import numpy as np
a = np.random.random(1000)
idx = np.array([1, 5, 89, 54])

# I want "data" array to have np.array([a[1:11], a[5:15], a[89:99], a[54:64]])
# I use for loop below but it is slow
data = []

for id in idx:
    data.append(a[id:id+10])  
data = np.array(data)

有没有办法加快这个过程?谢谢。

编辑:我的问题与here 提出的问题不同。在问题中,与我的问题中的固定块大小相比,块的大小是随机的。存在其他差异。我不必用完整个数组a,并且一个元素可以出现在多个块中。我的问题不一定“拆分”数组。

【问题讨论】:

  • 我假设 aones 出于问题的目的,对吗?
  • @Ivan 哈哈是的。我已将其编辑为现在具有随机值。
  • 这比较棘手,因为有重叠的部分!如果您执行np.split(a, idx),您将在索引15 上拆分数组,留下[array of size 1, array of size 4, ...,这不是您想要的结果。

标签: python arrays python-3.x list numpy


【解决方案1】:

(感谢@MadPhysicist 的建议)

这应该可行:

a[idx.reshape(-1, 1) + np.arange(10)]

输出: 形状(L,10),其中Lidx的长度

注意事项:

  1. 这不会检查索引超出范围的情况。我想首先确保idx 不包含此类值很容易。

  2. 使用np.take(a, idx.reshape(-1, 1) + np.arange(10), mode='wrap') 是一种替代方法,它将通过包裹a 来处理越界索引。传递mode='clip' 而不是mode='wrap' 会将多余的索引剪裁到a 的最后一个索引。但是,np.take() 可能会有完全不同的性能。特征/缩放特征。

【讨论】:

  • 我认为对索引进行排序可能会更快,尤其是对于短数组。 +1 任一方式
  • 另外,你真的不需要重塑和转置。输出数组是索引的形状。 idx.reshape(-1, 1) + np.arange(10) 就够了
  • @MadPhysicist -- 谢谢,已简化编辑。
  • 我们可以在编辑历史中看到编辑。无需在问答中标注“编辑”和“更新”。新手作者普遍存在一种误解,即人们希望看到除了您的精美产品之外的任何东西。
最近更新 更多