Iterar dos o más listas / matrices numpy … y comparar cada elemento entre sí y evitar bucles en python

Soy nuevo en Python y mi problema es el siguiente:

He definido una función func(a,b) que devuelve un valor, dados dos valores de entrada.

Ahora tengo mis datos almacenados en listas o arrays numpy A,B y me gustaría usar func para cada combinación. (A y B tienen más de un millón de entradas)

ATM uso este fragmento de código:

 for p in A: for k in B: value = func(p,k) 

Esto realmente toma mucho tiempo.

Así que estaba pensando que tal vez algo como esto:

 C=(map(func,zip(A,B))) 

Pero este método solo funciona en parejas … ¿Alguna idea?

Gracias por la ayuda

Supongamos que itertools.product hace lo que necesita:

 from itertools import product pro = product(A,B) C = map(lambda x: func(*x), pro) 

En la medida en que es generador no requiere memoria adicional.

Primer problema

Necesitas calcular la salida de f para muchos pares de valores. La forma “estándar” de acelerar este tipo de bucles (cálculos) es hacer que su función f acepte (NumPy) las matrices como entrada, y realice el cálculo en toda la matriz a la vez (es decir, sin ciclos como se ve desde Python). Consulte cualquier tutorial de NumPy para obtener una introducción.

Segundo problema

Si A y B tienen más de un millón de entradas cada una, hay un billón de combinaciones. Para números de 64 bits, eso significa que necesitará 7.3 TiB de espacio solo para almacenar el resultado de su cálculo. ¿Tienes suficiente disco duro para almacenar el resultado?

Tercer tema

Si A y B fueran mucho más pequeños, en su caso particular, podría hacer esto:

 values = f(*meshgrid(A, B)) 

meshgrid devuelve el producto cartesiano de A y B , por lo que es simplemente una forma de generar los puntos que deben evaluarse.

Resumen

  • Necesitas usar NumPy de manera efectiva para evitar los bucles de Python. (O si todo lo demás falla o no se pueden vectorizar fácilmente, escriba esos bucles en un lenguaje comstackdo, por ejemplo, utilizando Cython )

  • Trabajar con terabytes de datos es difícil. ¿Realmente necesitas tantos datos?

  • Cualquier solución que llame a una función f 1e12 veces en un bucle está destinada a ser lenta, especialmente en CPython (que es la implementación predeterminada de Python. Si no está realmente seguro y está usando NumPy, también lo está usando) .

Un millón de veces un millón es un billón. Llamar a un billón de veces tomará un tiempo.

A menos que tenga una forma de reducir el número de valores para calcular, no puede hacerlo mejor que lo anterior.

Si usa NumPy, definitivamente debería buscar la función np.vectorize que está diseñada para este tipo de problemas …