foo = np.array([1,2,3,4])
我有一個numpy的陣列foo
,我想變換成一個ndarry或矩陣,類似於:排列置換一個numpy的陣列的成ndarray或矩陣
bar = np.array([[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]])
如何任何建議要有效地做到這一點,因爲我的源數組foo
的大小會有所不同,而且我需要將此轉換數百萬次。
foo = np.array([1,2,3,4])
我有一個numpy的陣列foo
,我想變換成一個ndarry或矩陣,類似於:排列置換一個numpy的陣列的成ndarray或矩陣
bar = np.array([[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]])
如何任何建議要有效地做到這一點,因爲我的源數組foo
的大小會有所不同,而且我需要將此轉換數百萬次。
您可以在循環中使用np.roll
。
x = np.array([np.roll(foo, -x) for x in np.arange(foo.shape[0])])
print(x)
array([[1, 2, 3, 4],
[2, 3, 4, 1],
[3, 4, 1, 2],
[4, 1, 2, 3]])
對於大規模的性能,我們可以在這裏合併strides
。訣竅在於將原始數組與連續的最後一個元素的切片數組連接起來,然後獲取長度與原始數組長度相同的滑動窗口。
因此,實現將是 -
def strided_method(ar):
a = np.concatenate((ar, ar[:-1]))
L = len(ar)
n = a.strides[0]
return np.lib.stride_tricks.as_strided(a, (L,L), (n,n), writeable=False)
輸出將是隻讀的並且級聯陣列的視圖,因此將有一個恆定的時間幾乎不考慮數組的大小。這意味着一個非常有效的解決方案。如果您需要使用自己的內存空間進行寫入輸出,請在那裏複製副本,如後面的時間表所示。
採樣運行 -
In [51]: foo = np.array([1,2,3,4])
In [52]: strided_method(foo)
Out[52]:
array([[1, 2, 3, 4],
[2, 3, 4, 1],
[3, 4, 1, 2],
[4, 1, 2, 3]])
運行測試 -
In [53]: foo = np.random.randint(0,9,(1000))
# @cᴏʟᴅsᴘᴇᴇᴅ's loopy soln
In [54]: %timeit np.array([np.roll(foo, -x) for x in np.arange(foo.shape[0])])
100 loops, best of 3: 12.7 ms per loop
In [55]: %timeit strided_method(foo)
100000 loops, best of 3: 7.46 µs per loop
In [56]: %timeit strided_method(foo).copy()
1000 loops, best of 3: 454 µs per loop
正在等你發帖! –
這些矩陣稱爲漢克爾矩陣。大多數平臺都提供了創建它們的特定例程。您也可以通過刪除不必要的部分來提高速度來實現自己。這是a pretty concise code
from scipy.linalg import hankel
A = hankel([1,2,3,4], [4,1,2,3])
A
array([[1, 2, 3, 4],
[2, 3, 4, 1],
[3, 4, 1, 2],
[4, 1, 2, 3]])
看來,這只是〜2倍比Divakar的解決方案,它是出奇的快慢。
發佈的解決方案是否適合您? – Divakar