2012-10-12 90 views
10

Quiero crear la lista de puntos que corresponderían a una grilla. Entonces, si quiero crear una grilla de la región desde (0,0) a (1,1), contendría los puntos (0,0), (0,1), (1,0), (1, 0).Puntos numerados meshgrid

sé que que esto se puede hacer con el siguiente código:

g = np.meshgrid([0,1],[0,1]) 
np.append(g[0].reshape(-1,1),g[1].reshape(-1,1),axis=1) 

que arroje el resultado:

array([[0, 0], 
     [1, 0], 
     [0, 1], 
     [1, 1]]) 

Mi pregunta es doble:

  1. ¿Hay una mejor forma de hacer esto?
  2. ¿Hay alguna manera de generalizar esto en dimensiones más altas?

Respuesta

24

me he dado cuenta de que la documentación en numpy ofrece una forma más rápida de hacer esto:

X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] 
positions = np.vstack([X.ravel(), Y.ravel()]) 

Esta facilidad se puede generalizar a más dimensiones utilizando la función meshgrid2 vinculado y mapeo "de Ravel a la red resultante .

g = meshgrid2(x, y, z) 
positions = np.vstack(map(np.ravel, g)) 

El resultado es aproximadamente 35 veces más rápido que el método de cremallera para una matriz de 3D con 1000 garrapatas en cada eje.

Fuente: http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html#scipy.stats.gaussian_kde

Para comparar los dos métodos consideran las siguientes secciones de código:

Crear las marcas de graduación proverbiales que ayudarán a crear la red.

In [23]: import numpy as np 

In [34]: from numpy import asarray 

In [35]: x = np.random.rand(100,1) 

In [36]: y = np.random.rand(100,1) 

In [37]: z = np.random.rand(100,1) 

Definir la función que mgilson vinculada a la meshgrid:

In [38]: def meshgrid2(*arrs): 
    ....:  arrs = tuple(reversed(arrs)) 
    ....:  lens = map(len, arrs) 
    ....:  dim = len(arrs) 
    ....:  sz = 1 
    ....:  for s in lens: 
    ....:  sz *= s 
    ....:  ans = [] 
    ....:  for i, arr in enumerate(arrs): 
    ....:   slc = [1]*dim 
    ....:   slc[i] = lens[i] 
    ....:   arr2 = asarray(arr).reshape(slc) 
    ....:   for j, sz in enumerate(lens): 
    ....:    if j != i: 
    ....:     arr2 = arr2.repeat(sz, axis=j) 
    ....:   ans.append(arr2) 
    ....:  return tuple(ans) 

Crear la red y el tiempo de las dos funciones.

In [39]: g = meshgrid2(x, y, z) 

In [40]: %timeit pos = np.vstack(map(np.ravel, g)).T 
100 loops, best of 3: 7.26 ms per loop 

In [41]: %timeit zip(*(x.flat for x in g)) 
1 loops, best of 3: 264 ms per loop 
+0

Tengo un mensaje de error: 'Rastreo (llamada más reciente pasado): Archivo "", línea 1, en Archivo " \ xxx.py", línea 816, en meshgrid2 SLC [i] = lentes [ i] TypeError: el objeto 'map' no es subscripible 'file' xxx.py' es donde puse tu función. –

+0

Probablemente estés utilizando python3 donde map devuelve un iterador en lugar de una lista. Lo más fácil de hacer es envolver 'map' en' list': 'lens = list (map (len, arrs))'. –

+0

Por encima de Numpy 1.8 no hay necesidad de la función 'meshgrid2', porque' meshgrid' estándar admite dimensiones más altas. – fhchl

9

¿Sus puntos de conexión siempre son integrales? Si es así, usted podría utilizar numpy.ndindex

print list(np.ndindex(2,2)) 

dimensiones superiores:

print list(np.ndindex(2,2,2)) 

Por desgracia, esto no cumple los requisitos de la OP desde el supuesto integrante (empezando por 0) no se cumple . Dejaré esta respuesta solo en caso de que alguien más esté buscando lo mismo donde esas suposiciones son verdaderas.


Otra manera de hacer esto depende de zip:

g = np.meshgrid([0,1],[0,1]) 
zip(*(x.flat for x in g)) 

Esta porción escalas muy bien a las dimensiones arbitrarias. Desafortunadamente, np.meshgrid no se adapta bien a las dimensiones múltiples, por lo que esa parte tendrá que resolverse, o (suponiendo que funcione), puede utilizar este SO answer para crear su propia función ndmeshgrid.

+0

Buena sugerencia, pero por desgracia no lo son. Editar ... también los rangos no necesariamente comenzarán con el punto (0,0, ...). –

+0

@juniper - Muy mal. He agregado otra solución que podría ser de interés ... – mgilson

+0

Eso servirá. ¡Gracias! –

1

Sin embargo, otra manera de hacerlo es:

np.indices((2,2)).T.reshape(-1,2) 

¿Qué se puede generalizar a dimensiones más altas, por ejemplo .:

In [60]: np.indices((2,2,2)).T.reshape(-1,3) 
Out[60]: 
array([[0, 0, 0], 
     [1, 0, 0], 
     [0, 1, 0], 
     [1, 1, 0], 
     [0, 0, 1], 
     [1, 0, 1], 
     [0, 1, 1], 
     [1, 1, 1]]) 
Cuestiones relacionadas