簡體   English   中英

一維 NumPy 數組上的滑動標准差

[英]Sliding standard deviation on a 1D NumPy array

假設您有一個數組並想創建另一個數組,該數組的值連續等於第一個數組的 10 個元素的標准差。 在 for 循環的幫助下,它可以像下面的代碼一樣輕松編寫。 我想要做的是避免使用 for 循環來加快執行時間。 有什么建議嗎?

Code
a = np.arange(20)
b = np.empty(11)
for i in range(11):
    b[i] = np.std(a[i:i+10])

您可以使用np.lib.stride_tricks.as_strided創建一個滑動窗口的二維數組,它將是給定1D數組的視圖,因此不會占用更多內存。 然后,簡單地使用np.std沿着第二個軸(軸 = 1)以矢量化的方式獲得最終結果,就像這樣 -

W = 10 # Window size
nrows = a.size - W + 1
n = a.strides[0]
a2D = np.lib.stride_tricks.as_strided(a,shape=(nrows,W),strides=(n,n))
out = np.std(a2D, axis=1)

運行時測試

函數定義 -

def original_app(a, W):
    b = np.empty(a.size-W+1)
    for i in range(b.size):
        b[i] = np.std(a[i:i+W])
    return b
    
def vectorized_app(a, W):
    nrows = a.size - W + 1
    n = a.strides[0]
    a2D = np.lib.stride_tricks.as_strided(a,shape=(nrows,W),strides=(n,n))
    return np.std(a2D,1)

時間和驗證 -

In [460]: # Inputs
     ...: a = np.arange(10000)
     ...: W = 10
     ...: 

In [461]: np.allclose(original_app(a, W), vectorized_app(a, W))
Out[461]: True

In [462]: %timeit original_app(a, W)
1 loops, best of 3: 522 ms per loop

In [463]: %timeit vectorized_app(a, W)
1000 loops, best of 3: 1.33 ms per loop

所以,大約有400x加速!

為了完整起見,這是等效的熊貓版本-

import pandas as pd

def pdroll(a, W): # a is 1D ndarray and W is window-size
    return pd.Series(a).rolling(W).std(ddof=0).values[W-1:]

不是那么花哨,但沒有循環的代碼將是這樣的:

a = np.arange(20)
b = [a[i:i+10].std() for i in range(len(a)-10)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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