[英]Slice numpy array by chunks
我需要對給定定義切片條件的三個值( N1, N2, N3
)的數組( aa
)進行切片,如下所示:
import numpy as np
N1, N2, N3 = 200, 500000, 30
aa = np.random.uniform(0., 1., N1*N2)
bb = []
for i in range(N1):
bb += list(aa[i * N2:(i * N2) + N3])
這段代碼遵循以下規則生成一個新的數組bb
:
N3
的元件aa
N2
元素並添加以下N3
元素aa
aa
耗盡 我可以通過numpy索引更快地執行此過程嗎?
只需整形為2D
並切片第一個N3列-
bb = aa.reshape(N1,N2)[:,:N3].ravel()
當N3
超過N2
如果N3
超過N2
,則這些aa[i * N2:(i * N2) + N3]
在迭代中將有重疊。 為了解決這種情況,我們可以創建滑動窗口,然后切片行,直到我們有足夠的長度,然后為剩余的窗口創建一個循環-
from skimage.util.shape import view_as_windows
starts = np.arange(len(aa), step=N2)
lens = len(aa) - np.arange(len(aa), step=N2)
rem_lens = lens[lens < N3]
m0 = lens < N3
l1 = N3*(~m0).sum()
l2 = rem_lens.sum()
out = np.empty(l1+l2, dtype=aa.dtype)
out[:l1] = view_as_windows(aa,(N3))[::N2].ravel()
rem_starts = starts[m0]
ss = l1+np.r_[0,rem_lens.cumsum()]
for s,i,j in zip(rem_starts, ss[:-1], ss[1:]):
out[i:j] = aa[s:]
您可以通過重塑數組來更優雅地完成此操作。 首先將初始數組設為2D:
N1, N2, N3 = 200, 500000, 30
aa = np.random.uniform(0., 1., (N1, N2))
現在,只需沿第二維移除大小為N3
的塊即可:
bb = aa[:, :N3]
如果您需要bb
保持平坦,請使其:
bb = aa[:, :N3].ravel()
您可以使用NumPy的array_split
或split
來更簡單地完成相同的操作。
但是,它可能不會顯着提高效率 。
用aa[i * N2:(i * N2) + N3]
存儲一堆數組切片是切片數量的線性時間。 在NumPy內執行該循環(因此,假設您使用的是CPython,則在C循環而不是Python循環中執行)會更快一些。 但是,除非您有大量的切片,否則可能沒有關系。
但是,將每個切片轉換為具有list(aa[i * N2:(i * N2) + N3])
的列表,然后擴展現有列表,非常慢。 這可能要花費您總時間的99%以上,因此優化其他1%的問題是無關緊要的。 NumPy無法做任何加速將每個片段轉換為列表的操作。
因此,如果您實際上不需要列表,請停止調用list
。 你可以只使用數組列表和chain
需要他們在一起,或者你可以建立一個自定義跨入陣列出數組列表,或者你可以ravel
原來的數組你想要的形狀。
如果您確實需要一個列表,那從本質上來說很慢,而且您無能為力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.