web-dev-qa-db-fra.com

Le meilleur moyen d’initialiser et de remplir un tableau numpy?

Je veux initialiser et remplir un tableau numpy. Quel est le meilleur moyen?

Cela fonctionne comme je l'espère:

>>> import numpy as np
>>> np.empty(3)
array([ -1.28822975e-231,  -1.73060252e-077,   2.23946712e-314])

Mais cela ne veut pas: 

>>> np.empty(3).fill(np.nan)
>>> 

Rien? 

>>> type(np.empty(3))
<type 'numpy.ndarray'>

Il me semble que l'appel np.empty() renvoie le type d'objet correct. Je ne comprends donc pas pourquoi .fill() ne fonctionne pas? 

Assigner le résultat de np.empty() first fonctionne très bien:

>>> a = np.empty(3)
>>> a.fill(np.nan)
>>> a
array([ nan,  nan,  nan])

Pourquoi dois-je affecter une variable pour utiliser np.fill()? Est-ce que je manque une meilleure alternative?

24
tbc

np.fill modifie le tableau sur place et renvoie None. Par conséquent, si vous assignez le résultat à un nom, il prend la valeur None.

Une alternative consiste à utiliser une expression qui retourne nan, par exemple:

a = np.empty(3) * np.nan
25
shx2

Vous pouvez aussi essayer:

In [79]: np.full(3, np.nan)
Out[79]: array([ nan,  nan,  nan])

Le doc pertinent:

Definition: np.full(shape, fill_value, dtype=None, order='C')
Docstring:
Return a new array of given shape and type, filled with `fill_value`.

Bien que je pense que cela pourrait être uniquement disponible dans numpy 1.8+

38
JoshAdel

Je trouve cela facile à retenir:

numpy.array([numpy.nan]*3)

Par curiosité, je l'ai chronométré et les réponses de @ @ JoshAdel et de @ shx2 sont beaucoup plus rapides que les miennes avec de grands tableaux.

In [34]: %timeit -n10000 numpy.array([numpy.nan]*10000)
10000 loops, best of 3: 273 µs per loop

In [35]: %timeit -n10000 numpy.empty(10000)* numpy.nan
10000 loops, best of 3: 6.5 µs per loop

In [36]: %timeit -n10000 numpy.full(10000, numpy.nan)
10000 loops, best of 3: 5.42 µs per loop
3
ryanjdillon

Juste pour référence future, la multiplication par np.nan fonctionne uniquement à cause des propriétés mathématiques de np.nan. Pour une valeur générique N, il faudrait utiliser np.ones() * N imitant la réponse acceptée, cependant, en termes de vitesse, ce bon choix.

Le meilleur choix serait np.full() comme déjà indiqué, et si ce n'est pas disponible pour vous, np.zeros() + N semble être un meilleur choix que np.ones() * N, alors que np.empty() + N ou np.empty() * N ne sont tout simplement pas appropriés. Notez que np.zeros() + N fonctionnera également lorsque N sera np.nan.

%timeit x = np.full((1000, 1000, 10), 432.4)
8.19 ms ± 97.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.zeros((1000, 1000, 10)) + 432.4
9.86 ms ± 55.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.ones((1000, 1000, 10)) * 432.4
17.3 ms ± 104 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.array([432.4] * (1000 * 1000 * 10)).reshape((1000, 1000, 10))
316 ms ± 37.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1
norok2