Paralelizar una operación de vector Numpy

NumPy es una biblioteca que contiene objetos de array multidimensional, así como una colección de rutinas de procesamiento de array. No funciona en paralelo, como sabrá, sin embargo, realizar operaciones en paralelo puede proporcionarnos una gran ventaja de rendimiento. Usaremos la biblioteca numexpr para paralelizar las operaciones NumPy.

NúmExpr

NumExpr es un evaluador rápido de expresiones numéricas para NumPy. Las expresiones que actúan sobre la array, como 3*a+4*b (donde a y b son arrays), se aceleran y utilizan menos memoria que si se hicieran en Python. Además, sus capacidades de subprocesos múltiples pueden utilizar todos los núcleos, lo que resulta en una escala de rendimiento significativa en comparación con NumPy.

Para nuestras necesidades, usaremos la función de evaluación del paquete numexpr.

Sintaxis: numexpr.evaluate(ex, local_dict=Ninguno, global_dict=Ninguno, out=Ninguno, order=’K’, casting=’safe’, **kwargs)

Parámetros: 

  • ej: una string que forma una expresión que involucra los operandos y los operadores
  • local_dict: un diccionario que reemplaza los operandos locales en el marco actual.
  • global_dict: un diccionario que reemplaza los operandos globales en el marco actual.
  • out: Una array existente donde se almacenará el resultado. Se requiere cuidado para garantizar que el tamaño de esta array coincida con el tamaño de la array resultante.
  • order: controla el orden de iteración de los operandos.
  • casting: controla qué tipo de casting de datos puede ocurrir al hacer una copia o almacenamiento en búfer.

Devoluciones: Array resultante

Ejemplo 1:

En este ejemplo, he usado solo el parámetro ex de la función de evaluación para realizar la suma entre a y b.

Python3

import numpy as np
import numexpr as ne
  
a = np.array([[6, 6], [0, 7]])
b = np.array([[19, 17], [13, 19]])
  
print(ne.evaluate('a+b'))

Producción:

[[25. 23.]
[13. 26.]]

Ejemplo 2:

En este ejemplo, he usado el parámetro local_dict , junto con ex, para pasar operandos para c y d desde el ámbito local.

Python3

import numpy as np
import numexpr as ne
  
a = np.array([[6, 6], [0, 7]])
b = np.array([[19, 17], [13, 19]])
  
print(ne.evaluate('c+d', local_dict={'c': a, 'd': b}))

Producción:

[[25. 23.]
[13. 26.]]

Ejemplo 3:

En este ejemplo, he usado el parámetro global_dict para pasar el operando para d mientras que el parámetro local_dict para pasar el operando para c en el parámetro ex.

Python3

import numpy as np
import numexpr as ne
  
a = np.array([[6, 6], [0, 7]])
  
def calc():
    b = np.array([[19, 17], [13, 19]])
    out = np.zeros((2, 2))
    ne.evaluate('c+d', local_dict={'c': b},
                global_dict={'d': a}, out=out)
    print(out)
  
calc()

Producción:

[[25. 23.]
[13. 26.]]

Comparación de rendimiento

Ahora, pongamos a prueba nuestro aprendizaje. En los siguientes ejemplos, realizaremos las mismas operaciones usando NumPy y NumExpr y las cronometraremos usando timeit .

Ejemplo 1:

Realizaremos una expresión algebraica simple que involucre suma y multiplicación en vectores de dos filas, cada uno de tamaño 1000000. Para hacer eso, hemos usado funciones de suma y multiplicación del paquete NumPy y evaluación de NumExpr para imitarlo.

Python3

import numpy as np
import numexpr as ne
  
a = np.arange(1000000)
b = np.arange(1000000)
  
timeit np.add(np.multiply(2, a), np.multiply(4, b))
timeit ne.evaluate('2*a+4*b')

Producción:

Producción

Producción

Ejemplo 2:

En este ejemplo, usaremos la función sin de la biblioteca NumPy y su contraparte usando NumExpr para evaluar una función en un vector de fila de tamaño 1000000.

Python3

import numpy as np
import numexpr as ne
  
a = np.arange(1000000)
  
timeit np.sin(a)
timeit ne.evaluate('sin(a)')

Producción:

Producción

Producción

Ejemplo 3:

En este ejemplo, usaremos la función cos de la biblioteca NumPy y su contraparte usando la función de evaluación de NumExpr en una array de tamaño (10000, 10).

Python3

import numpy as np
import numexpr as ne
  
a = np.random.randint(0, 1000, size=(10000, 10))
  
timeit np.cos(a)
timeit ne.evaluate('cos(a)')

Producción:

Producción

Producción

Publicación traducida automáticamente

Artículo escrito por aayushmohansinha y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *