Estoy tratando de ejecutar el espacio de parámetros de una función de 6 parámetros para estudiar su comportamiento numérico antes de intentar hacer algo complejo con él, así que estoy buscando una manera eficiente de hacerlo.
Mi función toma valores flotantes dada una matriz numpy de 6 dim como entrada. Lo que intenté hacer inicialmente fue esto:
Primero creé una función que toma 2 matrices y genera una matriz con todas las combinaciones de valores de las dos matrices
from numpy import *
def comb(a,b):
c = []
for i in a:
for j in b:
c.append(r_[i,j])
return c
Luego solía reduce()
aplicar eso a m copias de la misma matriz:
def combs(a,m):
return reduce(comb,[a]*m)
Y luego evalúo mi función así:
values = combs(np.arange(0,1,0.1),6)
for val in values:
print F(val)
Esto funciona pero es muuuuy lento. Sé que el espacio de parámetros es enorme, pero esto no debería ser tan lento. Solo he muestreado 10 6 (un millón) puntos en este ejemplo y me llevó más de 15 segundos crear la matriz values
.
¿Conoces alguna forma más eficiente de hacer esto con numpy?
Puedo modificar la forma en que la función F
toma sus argumentos si es necesario.
fuente
Respuestas:
En la versión más reciente de
numpy
(> 1.8.x),numpy.meshgrid()
proporciona una implementación mucho más rápida:La solución de @ pv
numpy.meshgrid()
solía ser solo 2D, ahora es capaz de ND. En este caso, 3D:Tenga en cuenta que el orden de la resultante final es ligeramente diferente.
fuente
np.stack(np.meshgrid([1, 2, 3], [4, 5], [6, 7]), -1).reshape(-1, 3)
dará el orden correctoAquí hay una implementación puramente numpy. Es aproximadamente 5 veces más rápido que usar itertools.
fuente
from sklearn.utils.extmath import cartesian
TypeError: slice indices must be integers or None or have an __index__ method
lanzado porcartesian(arrays[1:], out=out[0:m,1:])
itertools.combinations es en general la forma más rápida de obtener combinaciones de un contenedor de Python (si de hecho quiere combinaciones, es decir, arreglos SIN repeticiones e independientes del orden; eso no es lo que parece estar haciendo su código, pero no puedo diga si eso se debe a que su código tiene errores o porque está usando la terminología incorrecta).
Si desea algo diferente a las combinaciones, quizás otros iteradores en itertools,
product
opermutations
, podrían servirle mejor. Por ejemplo, parece que su código es aproximadamente el mismo que:Todos estos iteradores producen tuplas, no listas o matrices numpy, por lo que si su F es exigente para obtener específicamente una matriz numpy, tendrá que aceptar la sobrecarga adicional de construir o borrar y volver a llenar una en cada paso.
fuente
Puedes hacer algo como esto
lo que da
fuente
La siguiente implementación numpy debería ser de aprox. 2 veces la velocidad de la respuesta dada:
fuente
np.indices((n,...,n)).reshape(k,-1).T
.Parece que desea una cuadrícula para evaluar su función, en cuyo caso puede usar
numpy.ogrid
(abrir) onumpy.mgrid
(desarrollar):fuente
puedes usar
np.array(itertools.product(a, b))
fuente
Aquí hay otra manera, usando NumPy puro, sin recursión, sin comprensión de la lista y sin explícito para los bucles. Es aproximadamente un 20% más lento que la respuesta original, y se basa en np.meshgrid.
Por ejemplo,
da
fuente
Para una implementación puramente numpy del producto cartesiano de matrices 1D (o listas planas de python), simplemente use
meshgrid()
, enrolle los ejes contranspose()
y vuelva a dar forma a la salida deseada:Tenga en cuenta que esto tiene la convención de que el último eje cambia más rápido ("estilo C" o "fila mayor").
Si desea cambiar el primer eje más rápido ("estilo FORTRAN" o "columna mayor"), simplemente cambie el
order
parámetro dereshape()
esta manera:reshape((-1, N), order='F')
fuente
Pandas
merge
ofrece una solución ingenua y rápida al problema:fuente