簡體   English   中英

按塊切片numpy數組

[英]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

  1. 第一N3的元件aa
  2. 跳轉N2元素並添加以下N3元素aa
  3. 重復2.直到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_splitsplit來更簡單地完成相同的操作。

但是,它可能不會顯着提高效率

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM