¿Existe una versión multidimensional de arange / linspace en numpy?

83

Me gustaría una lista de matrices 2d NumPy (x, y), donde cada x está en {-5, -4.5, -4, -3.5, ..., 3.5, 4, 4.5, 5} y lo mismo para y .

Yo podría hacer

x = np.arange(-5, 5.1, 0.5)
y = np.arange(-5, 5.1, 0.5)

y luego iterar a través de todos los pares posibles, pero estoy seguro de que hay una manera mejor ...

Me gustaría algo de vuelta que se parezca a:

[[-5, -5],
 [-5, -4.5],
 [-5, -4],
 ...
 [5, 5]]

pero el orden no importa.

Hilemonstoer
fuente
1
¿Tienes una pregunta? Editar: veo la preguntaxy = np.matrix([x, y])
Andy Kubiak
Esto simplemente concatena las dos matrices.
Hilemonstoer
1
Estoy un poco confundido, el "Me gustaría algo parecido a:" y "donde cada x está en {-5, -4.5, -4, -3.5, ..., 3.5, 4, 4.5, 5} y lo mismo para y "no parecen coincidir.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

78

Puede usarlo np.mgridpara esto, a menudo es más conveniente que np.meshgridporque crea las matrices en un solo paso:

import numpy as np
X,Y = np.mgrid[-5:5.1:0.5, -5:5.1:0.5]

Para una funcionalidad similar a linspace, reemplace el paso (es decir 0.5) con un número complejo cuya magnitud especifica el número de puntos que desea en la serie. Usando esta sintaxis, las mismas matrices que arriba se especifican como:

X, Y = np.mgrid[-5:5:21j, -5:5:21j]

Luego puede crear sus pares como:

xy = np.vstack((X.flatten(), Y.flatten())).T

Como sugirió @ali_m, todo esto se puede hacer en una línea:

xy = np.mgrid[-5:5.1:0.5, -5:5.1:0.5].reshape(2,-1).T

¡La mejor de las suertes!

farenorth
fuente
16
... o como una sola línea,xy = np.mgrid[-5:5.1:0.5, -5:5.1:0.5].reshape(2, -1).T
ali_m
23

Esto es justo lo que busca:

matr = np.linspace((1,2),(10,20),10)

Esto significa:

Para la primera columna; del 1 de (1,2) al 10 de (10,20), ponga los 10 números crecientes.

Para la segunda columna; del 2 de (1,2) al 20 de (10,20), ponga los 10 números crecientes.

Y el resultado será:

[[ 1.  2.]
 [ 2.  4.]
 [ 3.  6.]
 [ 4.  8.]
 [ 5. 10.]
 [ 6. 12.]
 [ 7. 14.]
 [ 8. 16.]
 [ 9. 18.]
 [10. 20.]]

También puede mantener aumentando solo los valores de una columna, por ejemplo, si dice que:

matr = np.linspace((1,2),(1,20),10)

La primera columna será de 1 de (1,2) a 1 de (1,20) por 10 veces lo que significa que permanecerá como 1 y el resultado será:

[[ 1.  2.]
 [ 1.  4.]
 [ 1.  6.]
 [ 1.  8.]
 [ 1. 10.]
 [ 1. 12.]
 [ 1. 14.]
 [ 1. 16.]
 [ 1. 18.]
 [ 1. 20.]]
Fırat Korkmaz
fuente
En numerosas versiones anteriores a la 1.16, esto arrojará un error. ver stackoverflow.com/questions/57269217/…
Techniquab
Esto no es bidimensional.
oulenz
¡también funciona con listas como entradas! Excelente como paso de preprocesamiento para meshgrid
Yuri Feldman
13

Creo que quieres np.meshgrid:

Devuelve matrices de coordenadas de vectores de coordenadas.

Cree matrices de coordenadas ND para evaluaciones vectorizadas de campos escalares / vectoriales ND sobre cuadrículas ND, dadas matrices de coordenadas unidimensionales x1, x2, ..., xn.

import numpy as np
x = np.arange(-5, 5.1, 0.5)
y = np.arange(-5, 5.1, 0.5)
X,Y = np.meshgrid(x,y)

puede convertir eso a su salida deseada con

XY=np.array([X.flatten(),Y.flatten()]).T

print XY
array([[-5. , -5. ],
       [-4.5, -5. ],
       [-4. , -5. ],
       [-3.5, -5. ],
       [-3. , -5. ],
       [-2.5, -5. ],
       ....
       [ 3. ,  5. ],
       [ 3.5,  5. ],
       [ 4. ,  5. ],
       [ 4.5,  5. ],
       [ 5. ,  5. ]])
tmdavison
fuente
Esto devuelve dos matrices grandes que creo que todavía necesitaría iterar para obtener la matriz de pares deseada. ¿Me equivoco?
Hilemonstoer
Vea mi edición: puede convertirlo a su matriz deseada con bastante facilidad sin iteración
tmdavison
La iteración casi nunca se requiere en numpy;)
OrangeSherbet
6

Si solo desea iterar a través de pares (y no hacer cálculos en todo el conjunto de puntos a la vez), lo mejor es itertools.productque itere a través de todos los pares posibles:

import itertools

for (xi, yi) in itertools.product(x, y):
    print(xi, yi)

Esto evita generar grandes matrices a través de meshgrid.

chthonicdaemon
fuente
5

Podemos utilizar la función de organizar como:

z1 = np.array([np.array(np.arange(1,5)),np.array(np.arange(1,5))])
print(z1)
o/p=> [[1 2 3 4]
       [1 2 3 4]]
Pranav Joshi
fuente
np.array(np.arange(?
CristiFati
Esto no es bidimensional.
oulenz
1

No estoy seguro de entender la pregunta: para hacer una lista de matrices NumPy de 2 elementos , esto funciona:

import numpy as np
x = np.arange(-5, 5.1, 0.5)
X, Y = np.meshgrid(x, x)
Liszt = [np.array(thing) for thing in zip(X.flatten(), Y.flatten())] # for python 2.7

zip le da una lista de tuplas y la comprensión de la lista hace el resto.

UH oh
fuente
0

No es una solución súper rápida, pero funciona para cualquier dimensión.

import numpy as np
def linspace_md(v_min,v_max,dim,num):
    output = np.empty( (num**dim,dim)  )
    values = np.linspace(v_min,v_max,num)
    for i in range(output.shape[0]):
        for d in range(dim):
            output[i][d] = values[( i//(dim**d) )%num]
    return output
cb1986ster
fuente
0

Todavía lo hice con Linspace porque prefiero ceñirme a este comando.

Puede crear como el siguiente formato: np.linspace (np.zeros ( ancho ) [0], np.full ((1, ancho ), - 1) [0], alto )

np.linspace(np.zeros(5)[0],np.full((1,5),-1)[0],5)

Salida de lo siguiente:

array([[ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [-0.25, -0.25, -0.25, -0.25, -0.25],
       [-0.5 , -0.5 , -0.5 , -0.5 , -0.5 ],
       [-0.75, -0.75, -0.75, -0.75, -0.75],
       [-1.  , -1.  , -1.  , -1.  , -1.  ]])

Agrega .tranpose () y obtienes:

array([[ 0.  , -0.25, -0.5 , -0.75, -1.  ],
      [ 0.  , -0.25, -0.5 , -0.75, -1.  ],
      [ 0.  , -0.25, -0.5 , -0.75, -1.  ],
      [ 0.  , -0.25, -0.5 , -0.75, -1.  ],
      [ 0.  , -0.25, -0.5 , -0.75, -1.  ]])
momo668
fuente
-1

Basado en este ejemplo, puede hacer cualquier atenuación que desee

def linspace3D(point1,point2,length):
    v1 = np.linspace(point1[0],point2[0],length)
    v2 = np.linspace(point1[1],point2[1],length)
    v3 = np.linspace(point1[2],point2[2],length)
    line = np.zeros(shape=[length,3])
    line[:,0]=v1
    line[:,1]=v2
    line[:,2]=v3
    return line
Martín
fuente