一维阵列的所有循环移位的二维数组

时间:2016-03-10 18:15:20

标签: numpy scipy vectorization

假设a是带有 n 元素的1d numppy.array

a = np.array([a_0, a_1, ..., a_n_minus_1])

我想在 i 行生成包含 i numpy.array i a的循环移位:

np.array([[a_0, a_1, ..., a_n_minus_1], [a_n_minus_1, a_0, a_1, ...], ...]])

最好没有循环。如何有效地完成这项工作?

(函数np.roll似乎相关,但显然只采用标量shift。)

2 个答案:

答案 0 :(得分:9)

你实际上正在建立一个循环矩阵。只需使用scipy circulant function即可。要小心,因为你必须传入第一个垂直列,而不是第一行:

from scipy.linalg import circulant
circulant([1,4,3,2]
> array([[1, 2, 3, 4],
         [4, 1, 2, 3],
         [3, 4, 1, 2],
         [2, 3, 4, 1]]

作为参考,循环矩阵非常好properties

答案 1 :(得分:2)

如果您想手动操作,请使用np.tile

import numpy as np
a = np.array([1,2,3])

使用瓷砖复制它,但实际需要的时间比获得所需的时间多一次" shift"

b = np.tile(a, a.size+1)
# [1 2 3 1 2 3 1 2 3 1 2 3]

然后重塑它,使其成为形状为(a, a+1)

的二维矩阵
b.reshape(a.size, a.size+1)
#[[1 2 3 1]
# [2 3 1 2]
# [3 1 2 3]]

好的,这只是调试步骤,看看发生了什么。但如果你看到它,你知道你只需要删除最后一列:

b.reshape(a.size, a.size+1)[:,:-1]

然后你就得到了你想要的结果。

这也可以概括为允许(几乎)任意转变:

shift = 3
a = np.array([...])
b = np.tile(a, a.size+shift)
res = b.reshape(a.size, a.size+shift)[:,:-shift]