簡體   English   中英

最有效的方法(lo <= k && k <= hi)? 1:0表示ka numpy數組,lo,hi常數

[英]Most efficient way to do (lo <= k && k <= hi) ? 1 : 0 for k a numpy array, lo, hi constants

我有一個大的numpy數組k ,具有未指定的形狀,我想構造一個相同形狀的數組d ,當k的相應條目在兩個常數lohi之間時為1.0,否則為0.0。 (因為什么較大的代碼是干什么的,我不想一個布爾值數組)。

顯而易見的方法是

d = np.ones_like(k)
d[np.less(k, lo)] = 0
d[np.greater(k, hi)] = 0

但是, np.lessnp.greater調用涉及創建大型臨時布爾數組,我測量這是一個重要的開銷。 有沒有辦法執行此操作,不涉及創建任何大型臨時對象,同時保持完全矢量化?

正如有人說,numpy的在臨時緩沖區沉重,它並沒有提供過它太多的控制。 如果內存占用確實是一個阻塞,你可以放入自己的小程序。 例如,

def process(x, lo, hi):
    """ lo <= x < hi ? 1.0 : 0.0."""
    x_shape = x.shape
    xx = np.ascontiguousarray(x).ravel()
    out = np.empty_like(xx)
    _process(xx, lo, hi, out)
    return out.reshape(x_shape)

_process在cython中的位置:

%%cython --annotate

import cython

@cython.boundscheck(False)
@cython.wraparound(False)
def _process(double[::1] x, double lo, double hi, double[::1] out):
    """ lo <= x < hi ? 1.0 : 0.0.""" 
    cdef:
        Py_ssize_t j
        double xj

    for j in range(x.shape[0]):
        xj = x[j]
        if lo <= xj < hi:
            out[j] = 1.0
        else:
            out[j] = 0.0

在這里我使用了jupyter筆記本(因此有趣的%%cython語法)。 在實際項目中,你需要輸入一個setup.py來編譯擴展等。這樣做的好處是否值得麻煩取決於你。

您可以根據比較創建布爾數組,然后轉換為浮點類型,一次性完成,如下所示 -

d = ((k >=lo) & (k <= hi)).astype(float)

lessgreater采取out參數:

out=np.ones_like(k)
np.less(k,80,out=out);
out &= np.greater(k,20);
# np.logical_and(np.greater(k,20),out,out=out);

這可能最終會保存一個中間數組。 雖然我與ufunc印象out的是,它仍然會創建一個臨時數組,但后來只是把它復制到out

在一個小的(10x10)陣列上,這比@ zwol的方法快,但比@Divakar的速度慢。 但差異並不大。

暫無
暫無

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

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