在numpy中列出范围列表

时间:2016-09-21 20:30:18

标签: python numpy

我想列出具有随机起点的整数序列。我在纯python中这样做的方式是

x = np.zeros(1000, 10) # 1000 sequences of 10 elements each
starts = np.random.randint(1, 1000, 1000)
for i in range(len(x)):
    x[i] = np.arange(starts[i], starts[i] + 10)

我想知道使用Numpy功能是否有更优雅的方式。

1 个答案:

答案 0 :(得分:0)

您可以在将starts扩展到2D版本并添加1D范围数组后使用broadcasting,就像这样 -

x = starts[:,None] + np.arange(10)

<强>解释

让我们以starts为例,了解broadcasting在这种情况下的作用。

In [382]: starts
Out[382]: array([3, 1, 3, 2])

In [383]: starts.shape
Out[383]: (4,)

In [384]: starts[:,None]
Out[384]: 
array([[3],
       [1],
       [3],
       [2]])

In [385]: starts[:,None].shape
Out[385]: (4, 1)

In [386]: np.arange(10).shape
Out[386]: (10,)

因此,观察形状并将它们放在一起,相同的示意图看起来像这样 -

starts         :  4
np.arange(10)  :  10

扩展starts后:

starts[:,None] :  4  x  1
np.arange(10)  :       10

因此,当我们使用starts[:,None]添加np.arange(10)时,starts[:,None]的元素将沿其第二个轴10广播,对应于另一个数组的长度那个轴。对于np.arange(10),它将被转换为2D,其第一个昏暗是单身昏暗,其元素沿4次广播,相应的长度为4沿该轴的其他数组starts[:,None]。请注意,没有明确的复制,因为在电子邮件中,元素被广播并在运行中添加。

因此,从功能上来说,我们会有复制,就像这样 -

In [391]: np.repeat(starts[:,None],10,axis=1)
Out[391]: 
array([[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
       [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]])

In [392]: np.repeat(np.arange(10)[None],4,axis=0)
Out[392]: 
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])

然后添加这些播放的元素,以便为我们提供所需的输出x