Eficient numpy atribuirea valorii prin intermediul boolean masca

0

Problema

Am un boolean masca valoare atribuirea problemă care necesită eficient boolean masca de funcționare.

Este un multi-dimensiune masca și eu sunt, folosind einsum pentru a obține rezultatul, dar operațiunea nu este foarte eficient, și mă întreb dacă pot obține ajutor Aici este soluția mea actuală: (ambele mask, truth_value, false_value sunt date fictive cu dtype și forma meciuri la problema mea.

mask = np.random.randn(1000, 50)> 0.5
truth_value = np.random.randn(50, 10)
false_value = np.random.randn(10)
objective = np.einsum('ij,jk->ijk', mask, truth_value) + np.einsum('ij,k->ijk', ~mask, false_value)

Există vreo modalitate mai rapidă de a obține objective dat mask, truth_value, false_value ?

În timp ce am fost de așteptare, dat seama de un mod mai rapid

objective = np.where(mask[...,np.newaxis], np.broadcast_to(truth_value, (1000, 50, 10)), np.broadcast_to(false_value,  (1000, 50, 10)))

Dar exista vreo alternativa mai repede ?

mask numpy python
2021-11-21 23:00:26
1

Cel mai bun răspuns

0

Puteți utiliza Mammas JIT pentru a face asta mai eficient.

import numpy as np
import numba as nb

@nb.njit('float64[:,:,::1](bool_[:,::1], float64[:,::1], float64[::1])')
def blend(mask, truth_value, false_value):
    n, m = mask.shape
    l = false_value.shape[0]
    assert truth_value.shape == (m, l)
    result = np.empty((n, m, l), dtype=np.float64)
    for i in range(n):
        for j in range(m):
            if mask[i, j]:
                result[i, j, :] = truth_value[j, :]
            else:
                result[i, j, :] = false_value[:]
    return result

mask = np.random.randn(1000, 50) > 0.5
truth_value = np.random.randn(50, 10)
false_value = np.random.randn(10)
objective = blend(mask, truth_value, false_value)

Calculul objective este de 4,8 ori mai repede pe masina mea.

Dacă acest lucru nu este suficient de rapid, puteți încerca pentru a paraleliza codul folosind parametrul parallel=True și folosind nb.prange în loc de range în am pe bază de buclă. Acest lucru nu poate fi mai rapid datorită aeriene de a crea subiecte noi. Pe masina mea (cu 6 nuclee), paralela versiune este de 7,4 ori mai repede (crearea de fire este destul de scump în comparație cu timpul de execuție).

O altă posibilă optimizare este de a scrie direct rezultatul într-un buffer alocat înainte de timp (acest lucru este doar mai bine daca ai apela această funcție de mai multe ori cu aceeași matrice de dimensiune).

Aici sunt în general timpii de pe masina mea:

np.einsum:         4.32 ms
np.where:          1.72 ms
numba sequential:  0.89 ms
numba parallel:    0.58 ms
2021-11-21 23:52:43

multumesc!!! acest lucru este într-adevăr mai repede decât einsum soluție! un pic mai repede decât np.where +np.broadcast_to soluție pe bază de.
yupbank

În alte limbi

Această pagină este în alte limbi

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................