initialiser un tableau numpy

129

Existe-t-il un moyen d'initialiser un tableau numpy d'une forme et d'y ajouter? Je vais expliquer ce dont j'ai besoin avec un exemple de liste. Si je veux créer une liste d'objets générés dans une boucle, je peux faire:

a = []
for i in range(5):
    a.append(i)

Je veux faire quelque chose de similaire avec un tableau numpy. Je connais vstack, concaténer etc. Cependant, il semble que ceux-ci nécessitent deux tableaux numpy comme entrées. Ce dont j'ai besoin c'est:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

Le big_arraydevrait avoir une forme (10,4). Comment faire cela?


ÉDITER:

Je veux ajouter la précision suivante. Je suis conscient que je peux le définir big_array = numpy.zeros((10,4))puis le remplir. Cependant, cela nécessite de spécifier la taille de big_array à l'avance. Je connais la taille dans ce cas, mais que faire si je ne le fais pas? Lorsque nous utilisons la .appendfonction pour étendre la liste en python, nous n'avons pas besoin de connaître sa taille finale à l'avance. Je me demande s'il existe quelque chose de similaire pour créer un plus grand tableau à partir de tableaux plus petits, en commençant par un tableau vide.

Curieux2learn
la source
Soit dit en passant votre premier exemple de code peut être écrit d'une manière ordonnée et succinctement comme la compréhension de la liste: [i for i in range(5)]. (De manière équivalente list(range(5))
:,
quelle solution a fonctionné pour vous? j'essaie de faire quelque chose de similaire comme x = numpy.array()nous le ferions pour une liste comme y = []; mais ça n'a pas fonctionné
kRazzy R

Réponses:

160

numpy.zeros

Renvoie un nouveau tableau de forme et de type donnés, rempli de zéros.

ou

numpy.ones

Renvoie un nouveau tableau de forme et de type donnés, rempli de uns.

ou

numpy.empty

Renvoie un nouveau tableau de forme et de type donnés, sans initialiser les entrées.


Cependant, la mentalité dans laquelle nous construisons un tableau en ajoutant des éléments à une liste n'est pas très utilisée dans numpy, car elle est moins efficace (les types de données numpy sont beaucoup plus proches des tableaux C sous-jacents). Au lieu de cela, vous devez préallouer le tableau à la taille dont vous avez besoin, puis remplir les lignes. Vous pouvez cependant l'utiliser numpy.appendsi vous le devez.

Katriel
la source
2
Je sais que je peux définir big_array = numpy.zeros puis le remplir avec les petits tableaux créés. Ceci, cependant, m'oblige à spécifier la taille de big_array à l'avance. N'y a-t-il rien de tel que .append de la fonction de liste où je n'ai pas le spécifier la taille à l'avance. Merci!
Curious2learn du
2
@ Curious2learn. Non, il n'y a rien de tel que l'ajout dans Numpy. Il existe des fonctions qui concaténent des tableaux ou les empilent en créant de nouveaux tableaux, mais elles ne le font pas en les ajoutant. Ceci est dû à la manière dont les structures de données sont configurées. Les tableaux Numpy sont conçus pour être rapides du fait qu'ils peuvent stocker des valeurs de manière plus compacte, mais ils doivent avoir une taille fixe pour obtenir cette vitesse. Les listes Python sont conçues pour être plus flexibles au détriment de la vitesse et de la taille.
Justin Peel du
3
@Curious: eh bien, il y a un appendin numpy. C'est juste qu'il est moins efficace de ne pas préallouer (dans ce cas, beaucoup moins efficace, car appending copie le tableau entier à chaque fois), donc ce n'est pas une technique standard.
Katriel
1
Et si seule une partie du np.emptytableau était remplie de valeurs? Qu'en est-il des éléments «vides» restants?
Lee
1
Si vous connaissez ne connaissez la largeur (par exemple nécessaire pour np.concatenate()), vous pouvez initialiser avec: np.empty((0, some_width)). 0, donc votre premier tableau ne sera pas des déchets.
NumesSanguis
40

La façon dont je le fais habituellement est de créer une liste régulière, puis d'y ajouter mes éléments, et enfin de transformer la liste en un tableau numpy comme suit:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

bien sûr, votre objet final prend deux fois plus d'espace dans la mémoire à l'étape de création, mais l'ajout sur la liste python est très rapide, et la création en utilisant np.array () également.

mad7777
la source
11
Ce n'est pas la voie à suivre si vous connaissez la taille du tableau à l'avance , cependant ... Je finis par utiliser cette méthode fréquemment quand je ne sais pas quelle sera la taille du tableau. Par exemple, lors de la lecture de données à partir d'un fichier ou d'un autre processus. Ce n'est pas vraiment aussi horrible que cela puisse paraître au premier abord puisque python et numpy sont assez intelligents.
travc
18

Introduit dans numpy 1.8:

numpy.full

Renvoie un nouveau tableau de forme et de type donnés, rempli de fill_value.

Exemples:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])
Franck Dernoncourt
la source
13

Array analogique pour les python

a = []
for i in range(5):
    a.append(i)

est:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)
Adobe
la source
5
@NicholasTJ: empty((0))initialise un tableau numpy.
Adobe
2
les crochets dans np.empty ((0)) sont redondants.
Szymon Roziewski
7

numpy.fromiter() est ce que vous recherchez:

big_array = numpy.fromiter(xrange(5), dtype="int")

Il fonctionne également avec des expressions de générateur, par exemple:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Si vous connaissez la longueur du tableau à l'avance, vous pouvez le spécifier avec un argument optionnel 'count'.

Métropole Quant
la source
2
En fait, j'ai exécuté timeit, et je pense que np.fromiter () pourrait être plus lent que np.array (). timeit ("np.array (i for i in xrange (100))", setup = "import numpy as np", number = 10000) -> 0.02539992332458496, versus timeit ("np.fromiter ((i for i in xrange ( 100)), dtype = int) ", setup =" import numpy as np ", number = 10000) -> 0.13351011276245117
hlin117
6

Vous voulez éviter autant que possible les boucles explicites lorsque vous faites du calcul par matrice, car cela réduit le gain de vitesse de cette forme de calcul. Il existe plusieurs façons d'initialiser un tableau numpy. Si vous voulez qu'il soit rempli de zéros, faites comme katrielalex a dit:

big_array = numpy.zeros((10,4))

EDIT: Quel genre de séquence faites-vous? Vous devriez vérifier les différentes fonctions numpy qui créent des tableaux, comme numpy.linspace(start, stop, size)(nombre également espacé), ou numpy.arange(start, stop, inc). Lorsque cela est possible, ces fonctions rendront les tableaux beaucoup plus rapides que de faire le même travail dans des boucles explicites

Andreas Løve Selvik
la source
5

Pour votre premier exemple de tableau, utilisez,

a = numpy.arange(5)

Pour initialiser big_array, utilisez

big_array = numpy.zeros((10,4))

Cela suppose que vous souhaitiez initialiser avec des zéros, ce qui est assez typique, mais il existe de nombreuses autres façons d'initialiser un tableau dans numpy .

Edit: Si vous ne connaissez pas la taille de big_array à l'avance, il est généralement préférable de créer d'abord une liste Python en utilisant append, et lorsque vous avez tout rassemblé dans la liste, convertissez cette liste en un tableau numpy en utilisant numpy.array(mylist). La raison en est que les listes sont censées se développer très efficacement et rapidement, alors que numpy.concatenate serait très inefficace car les tableaux numpy ne changent pas facilement de taille. Mais une fois que tout est rassemblé dans une liste et que vous connaissez la taille finale du tableau, un tableau numpy peut être construit efficacement.

tom10
la source
5

Pour initialiser un tableau numpy avec une matrice spécifique:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

production:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]
edW
la source
3

Chaque fois que vous vous trouvez dans la situation suivante:

a = []
for i in range(5):
    a.append(i)

et vous voulez quelque chose de similaire dans numpy, plusieurs réponses précédentes ont indiqué des moyens de le faire, mais comme @katrielalex l'a souligné, ces méthodes ne sont pas efficaces. Le moyen efficace de le faire est de créer une longue liste, puis de la remodeler comme vous le souhaitez après avoir une longue liste. Par exemple, disons que je lis quelques lignes d'un fichier et que chaque ligne a une liste de nombres et que je veux construire un tableau numpy de forme (nombre de lignes lues, longueur du vecteur dans chaque ligne). Voici comment je le ferais plus efficacement:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array
Heapify
la source
2

Je me rends compte que c'est un peu tard, mais je n'ai remarqué aucune des autres réponses mentionnant l'indexation dans le tableau vide:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

De cette façon, vous préallouez tout le tableau de résultats avec numpy.emptyet remplissez les lignes au fur et à mesure en utilisant l'affectation indexée.

Il est parfaitement sûr de préallouer avec emptyplutôt que zerosdans l'exemple que vous avez donné puisque vous garantissez que le tableau entier sera rempli avec les morceaux que vous générez.

Physicien fou
la source
2

Je suggérerais d'abord de définir la forme. Ensuite, parcourez-le pour insérer des valeurs.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])
GT GT
la source
1

Peut-être que quelque chose comme ça répondra à vos besoins.

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Qui produit la sortie suivante

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]

la source