亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

通過在numpy 1D數組中應用數學/邏輯更快地獲得每個尾巴 - 消除無窮大

通過在numpy 1D數組中應用數學/邏輯更快地獲得每個尾巴 - 消除無窮大

Qyouu 2022-08-02 17:09:26
我有一個2D數組,其中我需要獨立處理每個“列”(axis= 1)。對于每列(1D 數組),我需要一個應用于 1D 數組的每個長度尾部的函數,以提供長度為 N 的數組,如下所示。如何讓它更快?也許通過刪除 for 循環。我用map/lambda/hstack來做這件事,直到我命中了除以零的錯誤,這需要if/elif/else條件來消除行進到無窮大。import numpy as npx = np.random.rand(20,5)def get_updown_array(loc_array):    return np.array([updown(loc_array[x:]) for x in list(range(loc_array.shape[0]))])def updown(local_array):    sub_length = ((local_array.shape[0]) + 1) // 2 # to get the middle value when length is uneven    a = local_array[:sub_length].mean() # first half mean    b = local_array[-sub_length:].mean() # second half mean    if not a == 0:        return ( b - a ) / abs(a)    elif not b == 0:        return ( b - a ) / abs(( a + b ) / 2)    else:        return 0result = np.apply_along_axis(get_updown_array, 0, x)if/else 條件邏輯似乎消除了同時在一個 numpy 維度中跨多個值應用函數的能力。我研究了如何使用veyize,盡管這似乎仍然需要第一個函數中的for循環。我看了 pandas.apply,雖然它看起來更慢,之后仍然需要一個連接或 vstack/hstack?Cython被考慮過,盡管這仍然讓不雅的循環咯吱咯吱咯吱地溜走了。我嘗試了np.where,盡管這仍然需要一個for循環。有沒有辦法在沒有for循環的情況下將數學/邏輯應用于每個長度的尾部?最快的方法是什么?堆棧溢出社區。
查看完整描述

1 回答

?
嚕嚕噠

TA貢獻1784條經驗 獲得超7個贊

我會做這樣的事情:


def updown(x):

    result = np.zeros_like(x)

    for i in range(len(x)):

        mid = (len(x)+1)//2

        a = x[:mid].mean(axis=0)

        b = x[-mid:].mean(axis=0)

        mask_a = a != 0

        mask_b = (a == 0) & (b != 0)

        result[i, mask_a] = (b[mask_a] - a[mask_a]) / abs(a[mask_a])

        result[i, mask_b] = (b[mask_b] - a[mask_b]) / abs((a[mask_b] + b[mask_b])/2)

        x = x[1:]

    return result

在循環相當不可避免的情況下,最好預先分配結果數組(如果事先知道維度)并填充循環中的值。這還具有允許預先填充默認值零的優點。


無需在 列上應用任何內容,因為其他運算(和算術)可以很容易地應用于所選軸。xmean


條件邏輯是通過屏蔽實現的。


您還可以使用 和 關鍵字參數:outwherenp.divide


def updown(x):

    result = np.zeros_like(x)

    for i in range(len(x)):

        mid = (len(x)+1)//2

        a = x[:mid].mean(axis=0)

        b = x[-mid:].mean(axis=0)

        np.divide(b - a, abs(a), out=result[i], where=(a != 0))

        np.divide(b - a, abs((a + b)/2), out=result[i], where=(a == 0) & (b != 0))

        x = x[1:]

    return result

讓我們看看一些性能比較(我已經將整個原始代碼包裝在一個名為updown_orig)


對于維度,我們只看到 2 倍的改進:(20, 5)


In []: %timeit updown_orig(np.random.rand(20, 5))

1 ms ± 13.9 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In []: %timeit updown(np.random.rand(20, 5))

508 μs ± 10.2 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

讓我們將兩個維度縮放 10(將 大小增加 100 倍):x


In []: %timeit updown_orig(np.random.rand(200, 50))                                                                 

96.4 ms ± 1.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In []: %timeit updown(np.random.rand(200, 50))                                                                      

5.84 ms ± 64 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

現在,差異約為16.5倍。


查看完整回答
反對 回復 2022-08-02
  • 1 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號