我想找到一種簡潔的方法來從 numpy 陣列中采樣 n 步長為 m 的連續元素。最簡單的情況是以步長 2 采樣 1 個元素,這意味著獲取串列中的所有其他元素,可以這樣完成:
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[::2]
array([0, 2, 4, 6, 8])
但是,如果我想以 m 的步幅對 n 個連續元素進行切片,其中 n 和 m 可以是任意整數,該怎么辦?例如,如果我想以 3 的步幅對 2 個連續元素進行切片,我會得到如下結果:
array([0, 1, 3, 4, 6, 7, 9])
有沒有一種pythonic和簡潔的方式來做到這一點?謝謝!
uj5u.com熱心網友回復:
如果a足夠長,您可以重塑、切片和散開
a.reshape(-1,3)[:,:2].ravel()
但a必須是 (9,) 或 (12,)。結果仍然是副本。
建議:
np.lib.stride_tricks.as_strided(a, (4,2), (8*3, 8)).ravel()[:-1]
也是副本。該as_strided部分是一個視圖,但ravel會制作一個副本。還有那個額外元素的丑陋。
sliding_window_view被添加為更安全的版本:
In [81]: np.lib.stride_tricks.sliding_window_view(a,(3))
Out[81]:
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6],
[5, 6, 7],
[6, 7, 8],
[7, 8, 9]])
In [82]: np.lib.stride_tricks.sliding_window_view(a,(3))[::3,:2]
Out[82]:
array([[0, 1],
[3, 4],
[6, 7]])
再次ravel將制作副本。這省略了“額外” 9。
np.resize使用reshape填充(a根據需要重復):
In [83]: np.resize(a, (4,3))
Out[83]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[9, 0, 1]])
In [84]: np.resize(a, (4,3))[:,:2]
Out[84]:
array([[0, 1],
[3, 4],
[6, 7],
[9, 0]])
uj5u.com熱心網友回復:
此代碼可能有用,我在問題中的示例中對其進行了測驗 (n=2, m=3)
import numpy as np
def get_slice(arr, n, m):
b = np.array([])
for i in range(0, len(arr), m):
b = np.concatenate((b, arr[i:i n]))
return b
sliced_arr = get_slice(np.arange(10), n=2, m=3)
print(sliced_arr)
輸出
[0. 1. 3. 4. 6. 7. 9.]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/448642.html
