Necesito crear una matriz de longitud NumPy n
, cada elemento de los cuales es v
.
¿Hay algo mejor que:
a = empty(n)
for i in range(n):
a[i] = v
Sé zeros
y ones
funcionaría para v = 0, 1. Podría usar v * ones(n)
, pero no funcionará cuando lo sería mucho más lento.v
esté None
, y también
a = np.zeros(n)
en el bucle es más rápido quea.fill(0)
. Esto es contrario a lo que esperaba, ya que penséa=np.zeros(n)
que necesitaría asignar e inicializar nueva memoria. Si alguien puede explicar esto, lo agradecería.v * ones(n)
todavía es horrible, ya que utiliza la costosa multiplicación. Sin embargo, reemplace*
con+
, yv + zeros(n)
resulta ser sorprendentemente bueno en algunos casos ( stackoverflow.com/questions/5891410/… ).var = np.empty(n)
y luego llenarlo con 'var [:] = v'. (por cierto,np.full()
es tan rápido como esto)Respuestas:
Se introdujo NumPy 1.8
np.full()
, que es un método más directo que elempty()
seguidofill()
para crear una matriz llena de un cierto valor:Esta es posiblemente la forma de crear una matriz llena de ciertos valores, porque describe explícitamente lo que se está logrando (y en principio puede ser muy eficiente ya que realiza una tarea muy específica).
fuente
help(numpy.full)
en un shell de Python. También me sorprende que no esté en la documentación web.np.fill()
no existe y debería existirarr.fill()
), con una diferencia de aproximadamente 10%. Si la diferencia fuera mayor, plantearía un problema en el rastreador de errores NumPy. :) Prefiero un código más explícito y más claro, por una diferencia tan pequeña en el tiempo de ejecución, así que voy connp.full()
todo el tiempo.Actualizado para Numpy 1.7.0: (Hat-tip a @Rolf Bartstra.)
a=np.empty(n); a.fill(5)
Es el más rápido.En orden de velocidad descendente:
fuente
np.full()
sería útil. En mi máquina, con NumPy 1.8.1, es aproximadamente un 15% más lento que lafill()
versión menos directa (lo cual es inesperado, ya quefull()
tiene el potencial de ir un poco más rápido).fill()
es la solución más rápida. La solución de multiplicación es mucho más lenta.10000
lugar de1e4
hacer una diferencia notable, por alguna razón (full()
es casi un 50% más lento, con1e4
).full()
, se ejecuta considerablemente más lento cuando el tipo de datos no es explícitamente flotante. De lo contrario, es comparable (pero un poco más lento) con los mejores métodos aquí.full(100000, 5)
,full(100000, 5, dtype=float)
,full(100000, 5, dtype=int)
ya =np.empty(100000); a.fill(5)
todos toman casi al mismo tiempo en mi máquina (sin almacenamiento en caché:%timeit -r1 -n1 …
) (NumPy 1.11.2).Creo que
fill
es la forma más rápida de hacer esto.También debe evitar siempre iterar como lo hace en su ejemplo. Un simple
a[:] = v
logrará lo que hace su iteración usando una transmisión numpy .fuente
fill
, vi que serepeat
adapta aún mejor a mis necesidades.a[:]=v
es realmente más rápida en general que lafill
?fill
.Aparentemente, no solo las velocidades absolutas sino también el orden de velocidad (según lo informado por el usuario 1579844) dependen de la máquina; esto es lo que encontré:
a=np.empty(1e4); a.fill(5)
es el más rápidoEn orden de velocidad descendente:
Por lo tanto, intente averiguarlo y use lo que es más rápido en su plataforma.
fuente
yo tenía
en mente, pero aparentemente eso es más lento que todas las demás sugerencias para lo suficientemente grande
n
.Aquí hay una comparación completa con perfplot (un proyecto mío favorito).
Las dos
empty
alternativas siguen siendo las más rápidas (con NumPy 1.12.1).full
se pone al día con grandes matrices.Código para generar la trama:
fuente
Puede usar
numpy.tile
, por ejemplo:Aunque
tile
está destinado a 'en mosaico' una matriz (en lugar de un escalar, como en este caso), hará el trabajo, creando matrices precargadas de cualquier tamaño y dimensión.fuente
sin numpy
fuente
[v] * n
sería más directamente relevante a la pregunta de OP.