我有一個陣列a如下:
import numpy as np
a= np.array([[1, 3, 5, 7, 8, 7, 1],
[11, 13, 51, 17, 18, 17, 10]])
我想用滑動視窗構建該陣列的串列。這是我想要的輸出:

我使用了以下代碼,但它沒有提供我想要的輸出:
lag = 3
out = []
for i in range(2):
eachrow =[]
for col in range(a.shape[1]-lag):
X_row = []
xtmp = a[i, col:col lag]
X_row.append(xtmp)
ytmp = a[i, col lag]
X_row.append(ytmp)
eachrow.append(X_row)
out.append(eachrow)
任何幫助表示贊賞。謝謝。
uj5u.com熱心網友回復:
您可以使用numpy.lib.stride_tricks.sliding_window_view和numpy.apply_along_axis如下所示:
numpy.lib.stride_tricks.sliding_window_view是New in version 1.20.0.你需要更新你的 numpy
a = np.array([[1, 3, 5, 7, 8, 7, 1],[11, 13, 51, 17, 18, 17, 10]])
b = np.lib.stride_tricks.sliding_window_view(a.ravel(),4)
def create_array(row):
return np.array([row[:3],np.array(row[-1])], dtype=object)
c = np.apply_along_axis(create_array, 1, b)
print(c)
輸出:
[[array([1, 3, 5]) array(7)]
[array([3, 5, 7]) array(8)]
[array([5, 7, 8]) array(7)]
[array([7, 8, 7]) array(1)]
[array([8, 7, 1]) array(11)]
[array([ 7, 1, 11]) array(13)]
[array([ 1, 11, 13]) array(51)]
[array([11, 13, 51]) array(17)]
[array([13, 51, 17]) array(18)]
[array([51, 17, 18]) array(17)]
[array([17, 18, 17]) array(10)]]
uj5u.com熱心網友回復:
您的代碼產生:
In [3]: out
Out[3]:
[[[array([1, 3, 5]), 7],
[array([3, 5, 7]), 8],
[array([5, 7, 8]), 7],
[array([7, 8, 7]), 1]],
[[array([11, 13, 51]), 17],
[array([13, 51, 17]), 18],
[array([51, 17, 18]), 17],
[array([17, 18, 17]), 10]]]
這是一個長度為 2 的串列。在該串列中。
如果我們從中創建一個陣列 - 使用objectdtype,我們會得到一個 3d 陣列,其中一些元素是陣列,一些是整數:
In [6]: arr = np.array(out, object)
In [7]: arr
Out[7]:
array([[[array([1, 3, 5]), 7],
[array([3, 5, 7]), 8],
[array([5, 7, 8]), 7],
[array([7, 8, 7]), 1]],
[[array([11, 13, 51]), 17],
[array([13, 51, 17]), 18],
[array([51, 17, 18]), 17],
[array([17, 18, 17]), 10]]], dtype=object)
In [8]: arr.shape
Out[8]: (2, 4, 2)
將一行代碼更改為
X_row.append(np.array([ytmp]))
In [11]: np.array(out,object)
Out[11]:
array([[[array([1, 3, 5]), array([7])],
[array([3, 5, 7]), array([8])],
[array([5, 7, 8]), array([7])],
[array([7, 8, 7]), array([1])]],
[[array([11, 13, 51]), array([17])],
[array([13, 51, 17]), array([18])],
[array([51, 17, 18]), array([17])],
[array([17, 18, 17]), array([10])]]], dtype=object)
or displayed with the str/print array formatting:
In [12]: print(_)
[[[array([1, 3, 5]) array([7])]
[array([3, 5, 7]) array([8])]
[array([5, 7, 8]) array([7])]
[array([7, 8, 7]) array([1])]]
[[array([11, 13, 51]) array([17])]
[array([13, 51, 17]) array([18])]
[array([51, 17, 18]) array([17])]
[array([17, 18, 17]) array([10])]]]
We could reshape that to a (8,2) array (still object dtype):
In [14]: print(Out[11].reshape(-1,2))
[[array([1, 3, 5]) array([7])]
[array([3, 5, 7]) array([8])]
[array([5, 7, 8]) array([7])]
[array([7, 8, 7]) array([1])]
[array([11, 13, 51]) array([17])]
[array([13, 51, 17]) array([18])]
[array([51, 17, 18]) array([17])]
[array([17, 18, 17]) array([10])]]
Since the inner most arrays have a mixed size - some 3 some 1, the result can only be object dtype - or list of lists. That's isn't optimal for array calculations.
Commas are part of the display, along with [] and words like array. Together they give us clues as to the underlying objects, whether they are lists or arrays. Equally important are the shape and dtype (if the object is an array) or length if a list.
===
另一個答案使用striding_tricks函式。這是更詳細的方法。While xis a view,切片和整形會復制,所以很難說這是否更快。對于這個小例子,我敢打賭你的代碼更快,但對于更大的情況,它可能不會。
In [16]: np.lib.stride_tricks.sliding_window_view(a,(1,4))
Out[16]:
array([[[[ 1, 3, 5, 7]],
[[ 3, 5, 7, 8]],
[[ 5, 7, 8, 7]],
[[ 7, 8, 7, 1]]],
[[[11, 13, 51, 17]],
[[13, 51, 17, 18]],
[[51, 17, 18, 17]],
[[17, 18, 17, 10]]]])
In [17]: x = np.lib.stride_tricks.sliding_window_view(a,(1,4))
In [18]: x.shape
Out[18]: (2, 4, 1, 4)
這是原始 1d 陣列的 4d view。
您的大小為 3 的“陣列”可以從中分割:
In [19]: x[:,:,0,:3]
Out[19]:
array([[[ 1, 3, 5],
[ 3, 5, 7],
[ 5, 7, 8],
[ 7, 8, 7]],
[[11, 13, 51],
[13, 51, 17],
[51, 17, 18],
[17, 18, 17]]])
In [20]: x[:,:,0,:3].reshape(-1,3)
Out[20]:
array([[ 1, 3, 5],
[ 3, 5, 7],
[ 5, 7, 8],
[ 7, 8, 7],
[11, 13, 51],
[13, 51, 17],
[51, 17, 18],
[17, 18, 17]])
和 1 元素列:
In [21]: x[:,:,0,-1].reshape(-1,1)
Out[21]:
array([[ 7],
[ 8],
[ 7],
[ 1],
[17],
[18],
[17],
[10]])
這 2 個陣列可能比您的 object 更有用out。
[14] 中顯示的陣列可以拆分為 2 個類似的陣列:
In [27]: np.stack(arr.reshape(-1,2)[:,0])
Out[27]:
array([[ 1, 3, 5],
[ 3, 5, 7],
[ 5, 7, 8],
[ 7, 8, 7],
[11, 13, 51],
[13, 51, 17],
[51, 17, 18],
[17, 18, 17]])
In [28]: arr.reshape(-1,2)[:,1].astype(int)
Out[28]: array([ 7, 8, 7, 1, 17, 18, 17, 10])
uj5u.com熱心網友回復:
我看到有兩個問題:
視窗中的最后一個元素未包含在
np.array.然后,快速解決方法是更改??此行:
X_row.append(ytmp)到
X_row.append(np.array([ytmp]))這會產生所需的輸出。
結果是二維的,因為您為陣列中的每一行創建一個單獨的子串列,然后將該子串列附加到結果中。要解決,請更改:
out.append(eachrow)到
out.extend(eachrow)
uj5u.com熱心網友回復:
您可以使用numpy.lib.stride_tricks.sliding_window_view快速的矢量化解決方案:
x = np.lib.stride_tricks.sliding_window_view(a, (1,3))[:, :-1]
x.shape = (*x.shape[:2], *x.shape[3:])
y = a[:, -x.shape[1]:, None]
輸出:
>>> x
array([[[ 1, 3, 5],
[ 3, 5, 7],
[ 5, 7, 8],
[ 7, 8, 7]],
[[11, 13, 51],
[13, 51, 17],
[51, 17, 18],
[17, 18, 17]]])
>>> y
array([[[ 7],
[ 8],
[ 7],
[ 1]],
[[17],
[18],
[17],
[10]]])
現在,只需使用zip list:
out = [list(zip(x[i], y[i])) for i in range(len(y))]
輸出:
>>> out
[[(array([1, 3, 5]), array([7])),
(array([3, 5, 7]), array([8])),
(array([5, 7, 8]), array([7])),
(array([7, 8, 7]), array([1]))],
[(array([11, 13, 51]), array([17])),
(array([13, 51, 17]), array([18])),
(array([51, 17, 18]), array([17])),
(array([17, 18, 17]), array([10]))]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/449879.html
