J'ai besoin de créer un tableau NumPy de longueur n
, dont chaque élément est v
.
Y a-t-il quelque chose de mieux que:
a = empty(n)
for i in range(n):
a[i] = v
Je sais que zeros
et ones
fonctionneraient pour v = 0, 1. Je pourrais utiliser v * ones(n)
, mais ne fonctionnera pas quand serait beaucoup plus lent.v
est None
, et aussi
NumPy 1.8 introduit np.full()
, méthode plus directe que empty()
suivie de fill()
pour créer un tableau rempli d'une certaine valeur:
>>> 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]])
C’est sans doute le moyen de créer un tableau rempli de certaines valeurs, car il décrit explicitement ce qui est en train d’être réalisé (et il peut en principe être très efficace puisque il effectue une tâche très spécifique).
Mise à jour pour Numpy 1.7.0: (Hat-tip à @Rolf Bartstra.)
a=np.empty(n); a.fill(5)
est le plus rapide.
En ordre de vitesse décroissant:
%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
Apparemment, non seulement les vitesses absolues mais également la vitesse ordre (telle que rapportée par l'utilisateur1579844) dépendent de la machine; voici ce que j'ai trouvé:
a=np.empty(1e4); a.fill(5)
est le plus rapide;
En ordre de vitesse décroissant:
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!)
Essayez donc de savoir et d’utiliser ce qui est le plus rapide sur votre plate-forme.
J'avais
numpy.array(n * [value])
à l'esprit, mais apparemment, c'est plus lent que toutes les autres suggestions assez grandes n
.
Voici une comparaison complète avec perfplot (un de mes projets pour animaux de compagnie).
Les deux alternatives empty
sont toujours les plus rapides (avec NumPy 1.12.1). full
rattrape les grands tableaux.
Code pour générer l'intrigue:
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,
)
Vous pouvez utiliser numpy.tile
, par exemple. :
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]])
Bien que tile
soit destiné à "paver" un tableau (au lieu d'un scalaire, comme dans ce cas), il effectuera le travail en créant des tableaux préremplis de toutes tailles et de toutes dimensions.
sans numpy
>>>[2]*3
[2, 2, 2]