Inicialización de matriz NumPy (rellenar con valores idénticos)


Necesito crear una matriz NumPy de length n, cada elemento de los cuales es v.

¿Hay algo mejor que:

a = empty(n)
for i in range(n):
    a[i] = v

Sé que zeros y ones funcionaría para v = 0, 1. Podría usar v * ones(n), pero no funcionará cuando v es None, y también sería mucho más lento.

Author: Peter Mortensen, 2011-05-05

7 answers

NumPy 1.8 introducido np.full(), que es un método más directo que empty() seguido de fill() para crear una matriz llena de un cierto valor:

>>> np.full((3, 5), 7)
array([[ 7.,  7.,  7.,  7.,  7.],
       [ 7.,  7.,  7.,  7.,  7.],
       [ 7.,  7.,  7.,  7.,  7.]])

>>> np.full((3, 5), 7, dtype=int)
array([[7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7]])

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).

 189
Author: Eric Lebigot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-05 15:03:25

Actualizado para Numpy 1.7.0: (Hat-tip para @Rolf Bartstra.)

a=np.empty(n); a.fill(5) es el más rápido.

En orden descendente de velocidad:

%timeit a=np.empty(1e4); a.fill(5)
100000 loops, best of 3: 5.85 us per loop

%timeit a=np.empty(1e4); a[:]=5 
100000 loops, best of 3: 7.15 us per loop

%timeit a=np.ones(1e4)*5
10000 loops, best of 3: 22.9 us per loop

%timeit a=np.repeat(5,(1e4))
10000 loops, best of 3: 81.7 us per loop

%timeit a=np.tile(5,[1e4])
10000 loops, best of 3: 82.9 us per loop
 79
Author: Yariv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-03 08:25:06

Creo fill es la forma más rápida de hacer esto.

a = np.empty(10)
a.fill(7)

También debe evitar siempre iterar como lo está haciendo en su ejemplo. Un simple a[:] = v logrará lo que tu iteración hace usando numpy broadcasting.

 55
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-05 16:10:46

Aparentemente, no solo las velocidades absolutas sino también la velocidad orden (según lo informado por user1579844) dependen de la máquina; esto es lo que encontré:

a=np.empty(1e4); a.fill(5) es el más rápido;

En orden descendente de velocidad:

timeit a=np.empty(1e4); a.fill(5) 
# 100000 loops, best of 3: 10.2 us per loop
timeit a=np.empty(1e4); a[:]=5
# 100000 loops, best of 3: 16.9 us per loop
timeit a=np.ones(1e4)*5
# 100000 loops, best of 3: 32.2 us per loop
timeit a=np.tile(5,[1e4])
# 10000 loops, best of 3: 90.9 us per loop
timeit a=np.repeat(5,(1e4))
# 10000 loops, best of 3: 98.3 us per loop
timeit a=np.array([5]*int(1e4))
# 1000 loops, best of 3: 1.69 ms per loop (slowest BY FAR!)

Por lo tanto, tratar de averiguar, y utilizar lo que es más rápido en su plataforma.

 13
Author: Rolf Bartstra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-05 14:07:57

Tenía

numpy.array(n * [value])

En mente, pero aparentemente eso es más lento que todas las otras sugerencias para lo suficientemente grande n.

Aquí hay una comparación completa con perfplot (un proyecto favorito mío).

introduzca la descripción de la imagen aquí

Las dos alternativas empty siguen siendo las más rápidas (con NumPy 1.12.1). full capturas para matrices grandes.


Código para generar el gráfico:

import numpy as np
import perfplot


def empty_fill(n):
    a = np.empty(n)
    a.fill(3.14)
    return a


def empty_colon(n):
    a = np.empty(n)
    a[:] = 3.14
    return a


def ones_times(n):
    return 3.14 * np.ones(n)


def repeat(n):
    return np.repeat(3.14, (n))


def tile(n):
    return np.repeat(3.14, [n])


def full(n):
    return np.full((n), 3.14)


def list_to_array(n):
    return np.array(n * [3.14])


perfplot.show(
    setup=lambda n: n,
    kernels=[
        empty_fill, empty_colon, ones_times, repeat, tile, full, list_to_array
        ],
    n_range=[2**k for k in range(27)],
    xlabel='len(a)',
    logx=True,
    logy=True,
    )
 9
Author: Nico Schlömer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-05 13:12:12

Puede usar numpy.tile, por ejemplo:

v = 7
rows = 3
cols = 5
a = numpy.tile(v, (rows,cols))
a
Out[1]: 
array([[7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7]])

Aunque tile está destinado a 'tile' una matriz (en lugar de un escalar, como en este caso), hará el trabajo, creando matrices precargadas de cualquier tamaño y dimensión.

 6
Author: Rolf Bartstra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-23 15:51:07

Sin numpy

>>>[2]*3
[2, 2, 2]
 0
Author: Mr.Green,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-09 13:02:50