web-dev-qa-db-fra.com

Echec de l'ajout à un tableau NumPy vide

J'essaie de remplir un tableau vide (pas np.empty!) Avec des valeurs en utilisant append mais je suis gettin erreur:

Mon code est le suivant:

import numpy as np
result=np.asarray([np.asarray([]),np.asarray([])])
result[0]=np.append([result[0]],[1,2])

Et j'obtiens:

ValueError: could not broadcast input array from shape (2) into shape (0)
30
Cupitor

numpy.append Est assez différent de list.append en python. Je sais que cela a jeté quelques programmeurs débutants sur numpy. numpy.append Ressemble plus à concaténer, il crée un nouveau tableau et le remplit avec les valeurs de l'ancien tableau et les nouvelles valeurs à ajouter. Par exemple:

import numpy

old = numpy.array([1, 2, 3, 4])
new = numpy.append(old, 5)
print old
# [1, 2, 3, 4]
print new
# [1, 2, 3, 4, 5]
new = numpy.append(new, [6, 7])
print new
# [1, 2, 3, 4, 5, 6, 7]

Je pense que vous pourrez peut-être atteindre votre objectif en faisant quelque chose comme:

result = numpy.zeros((10,))
result[0:2] = [1, 2]

# Or
result = numpy.zeros((10, 2))
result[0, :] = [1, 2]

Mise à jour:

Si vous devez créer un tableau numpy à l'aide de la boucle et que vous ne savez pas à l'avance quelle sera la taille finale du tableau, vous pouvez procéder comme suit:

import numpy as np

a = np.array([0., 1.])
b = np.array([2., 3.])

temp = []
while True:
    rnd = random.randint(0, 100)
    if rnd > 50:
        temp.append(a)
    else:
        temp.append(b)
    if rnd == 0:
         break

 result = np.array(temp)

Dans mon exemple, le résultat sera un tableau (N, 2), où N est le nombre de fois que la boucle a été exécutée, mais vous pouvez évidemment l'ajuster à vos besoins.

nouvelle mise à jour

L'erreur que vous voyez n'a rien à voir avec des types, mais avec la forme des tableaux numpy que vous essayez de concaténer. Si vous faites np.append(a, b), les formes de a et b doivent correspondre. Si vous ajoutez un (2, n) et un (n,) vous obtiendrez un tableau (3, n). Votre code tente d’ajouter un (1, 0) à un (2,). Ces formes ne correspondent pas, vous obtenez donc une erreur.

35
Bi Rico

Je comprends peut-être mal la question, mais si vous souhaitez déclarer un tableau d’une certaine forme mais ne contenant rien, les informations suivantes peuvent être utiles:

Initialise un tableau vide:

>>> a = np.zeros((0,3)) #or np.empty((0,3)) or np.array([]).reshape(0,3)
>>> a
array([], shape=(0, 3), dtype=float64)

Vous pouvez maintenant utiliser ce tableau pour y ajouter des rangées de forme similaire. Rappelez-vous qu'un tableau numpy est immuable, donc un nouveau tableau est créé pour chaque itération:

>>> for i in range(3):
...     a = np.vstack([a, [i,i,i]])
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

np.vstack et np.hstack sont la méthode la plus courante pour combiner des tableaux numpy, mais venant de Matlab, je préfère np.r_ et np.c_:

concaténer 1d:

>>> a = np.zeros(0)
>>> for i in range(3):
...     a = np.r_[a, [i, i, i]]
...
>>> a
array([ 0.,  0.,  0.,  1.,  1.,  1.,  2.,  2.,  2.])

Concaténer des lignes:

>>> a = np.zeros((0,3))
>>> for i in range(3):
...     a = np.r_[a, [[i,i,i]]]
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

Concaténer les colonnes:

>>> a = np.zeros((3,0))
>>> for i in range(3):
...     a = np.c_[a, [[i],[i],[i]]]
...
>>> a
array([[ 0.,  1.,  2.],
       [ 0.,  1.,  2.],
       [ 0.,  1.,  2.]])
67
Simon Streicher

Cette erreur provient du fait que vous essayez de définir un objet de forme (0,) en tant qu'objet de forme (2,). Si vous ajoutez ce que vous voulez sans le forcer à être égal au résultat [0], il n'y a pas de problème:

b = np.append([result[0]], [1,2])

Mais lorsque vous définissez result [0] = b, vous assimilez des objets de formes différentes et vous ne pouvez pas le faire. Qu'essayez-vous de faire?

4
Alejandro

Voici le résultat de l'exécution de votre code dans Ipython. Notez que result est un tableau (2,0), 2 lignes, 0 colonnes, 0 éléments. Le append produit un tableau (2,). result[0] Est un tableau (0,). Votre message d'erreur consiste à essayer d'affecter ce tableau de 2 éléments à un emplacement de taille 0. Puisque result est dtype=float64, Seuls les scalaires peuvent être affectés à ses éléments.

In [65]: result=np.asarray([np.asarray([]),np.asarray([])])

In [66]: result
Out[66]: array([], shape=(2, 0), dtype=float64)

In [67]: result[0]
Out[67]: array([], dtype=float64)

In [68]: np.append(result[0],[1,2])
Out[68]: array([ 1.,  2.])

np.array N'est pas une liste Python. Tous les éléments d'un tableau sont du même type (comme spécifié par le dtype). Notez également que result n'est pas un tableau de tableaux.

Le résultat aurait également pu être construit comme

ll = [[],[]]
result = np.array(ll)

tandis que

ll[0] = [1,2]
# ll = [[1,2],[]]

le même n'est pas vrai pour le résultat.

np.zeros((2,0)) produit également votre result.

En fait, il y a un autre problème avec result.

result[0] = 1

ne change pas les valeurs de result. Il accepte l'affectation, mais comme il a 0 colonne, il n'y a pas de place pour mettre le 1. Cette affectation fonctionnerait dans le résultat a été créé en tant que np.zeros((2,1)). Mais cela ne peut toujours pas accepter une liste.

Mais si result a 2 colonnes, vous pouvez affecter une liste de 2 éléments à l'une de ses lignes.

result = np.zeros((2,2))
result[0] # == [0,0]
result[0] = [1,2]

À quoi voulez-vous que result ressemble après l'opération append?

3
hpaulj

numpy.append copie toujours le tableau avant d’ajouter les nouvelles valeurs. Votre code est équivalent à celui-ci:

import numpy as np
result = np.zeros((2,0))
new_result = np.append([result[0]],[1,2])
result[0] = new_result # ERROR: has shape (2,0), new_result has shape (2,)

Vous voulez peut-être faire cela?

import numpy as np
result = np.zeros((2,0))
result = np.append([result[0]],[1,2])
2
Stuart Berg

SO thread ' Multipliez deux tableaux par élément, où l'un des tableaux a des tableaux comme éléments ' présente un exemple de construction d'un tableau à partir de tableaux. Si les sous-tableaux ont la même taille, numpy crée un tableau 2d. Mais s'ils diffèrent en longueur, un tableau avec dtype=object Est créé, et les sous-tableaux conservent leur identité.

Après cela, vous pourriez faire quelque chose comme ça:

In [5]: result=np.array([np.zeros((1)),np.zeros((2))])

In [6]: result
Out[6]: array([array([ 0.]), array([ 0.,  0.])], dtype=object)

In [7]: np.append([result[0]],[1,2])
Out[7]: array([ 0.,  1.,  2.])

In [8]: result[0]
Out[8]: array([ 0.])

In [9]: result[0]=np.append([result[0]],[1,2])

In [10]: result
Out[10]: array([array([ 0.,  1.,  2.]), array([ 0.,  0.])], dtype=object)

Cependant, je ne vois pas quels avantages cela a par rapport à une liste pure Python). Cela ne fonctionne pas comme un tableau 2d. Par exemple, je dois utiliser result[0][1] , pas result[0,1]. Si les sous-tableaux ont tous la même longueur, je dois utiliser np.array(result.tolist()) pour produire un tableau 2d.

1
hpaulj