【发布时间】:2017-01-30 06:20:17
【问题描述】:
我想制作一个具有随机起点的整数序列列表。我在纯 python 中这样做的方式是
x = np.zeros(1000, 10) # 1000 个序列,每个序列 10 个元素 开始 = np.random.randint(1, 1000, 1000) 对于我在范围内(len(x)): x[i] = np.arange(开始[i], 开始[i] + 10)我想知道使用 Numpy 功能是否有更优雅的方法。
【问题讨论】:
我想制作一个具有随机起点的整数序列列表。我在纯 python 中这样做的方式是
x = np.zeros(1000, 10) # 1000 个序列,每个序列 10 个元素 开始 = np.random.randint(1, 1000, 1000) 对于我在范围内(len(x)): x[i] = np.arange(开始[i], 开始[i] + 10)我想知道使用 Numpy 功能是否有更优雅的方法。
【问题讨论】:
您可以在将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时间对应于另一个数组starts[:,None]的4的长度沿该轴.请注意,没有明确的复制,因为在后台,elems 是动态广播和添加的。
因此,在功能上我们会有复制,就像这样 -
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。
【讨论】:
broadcasting 的概念,我建议您自己阅读文档。