194 votes

Numpy - ajouter une ligne au tableau

Comment ajouter des lignes à un tableau numpy ?

J'ai un tableau A :

A = array([[0, 1, 2], [0, 2, 0]])

Je souhaite ajouter des lignes à ce tableau à partir d'un autre tableau X si le premier élément de chaque ligne de X répond à une condition spécifique.

Les tableaux Numpy ne disposent pas d'une méthode "append" comme celle des listes, du moins c'est ce qu'il semble.

Si A et X étaient des listes, je me contenterais de faire :

for i in X:
    if i[0] < 3:
        A.append(i)

Y a-t-il un numpythonique manière de faire l'équivalent ?

Merci, S ;-)

0 votes

187voto

jknair Points 1708

Vous pouvez le faire :

  newrow = [1,2,3]
  A = numpy.vstack([A, newrow])

2 votes

@Kris Pourquoi est-il déprécié ? Je ne vois rien dans docs

1 votes

@Georgy Pour être honnête, je ne sais pas. J'étais ici à la recherche de réponses, tout comme vous :-). Je ne me souviens plus pourquoi j'ai écrit le commentaire ci-dessus. J'ai dû voir dans la docs qu'il était déprécié. Mais en regardant la docs maintenant ... il ne le dit pas. Est-il possible qu'ils l'aient déprécié, puis aient changé d'avis et décidé que ce serait trop ennuyeux pour trop de gens de le déprécier et de le supprimer ?

145voto

eumiro Points 56644

Qu'est-ce que X ? S'il s'agit d'un tableau en 2D, comment pouvez-vous alors comparer sa ligne à un nombre ? i < 3 ?

EDIT après le commentaire de l'OP :

A = array([[0, 1, 2], [0, 2, 0]])
X = array([[0, 1, 2], [1, 2, 0], [2, 1, 2], [3, 2, 0]])

ajouter à A toutes les lignes de X où le premier élément < 3 :

import numpy as np
A = np.vstack((A, X[X[:,0] < 3]))

# returns: 
array([[0, 1, 2],
       [0, 2, 0],
       [0, 1, 2],
       [1, 2, 0],
       [2, 1, 2]])

1 votes

Désolé, bonne remarque ! Supposons un tableau 2D dont le premier élément de chaque ligne doit remplir une condition. Je vais modifier cela. Merci, S ;-)

2 votes

@DarrenJ.Fitzpatrick Gardez à l'esprit qu'en faisant ce type de manipulation, vous allez à l'encontre du bon travail que fait Numpy en pré-allouant la mémoire pour votre tableau existant. A . Il est clair que pour les petits problèmes comme dans cette réponse, ce n'est pas un problème, mais cela peut être plus troublant pour les grandes données.

41voto

Flora PJ Li Points 559

Comme cette question date de 7 ans, dans la dernière version que j'utilise, numpy version 1.13, et python3, je fais la même chose avec l'ajout d'une ligne à une matrice, n'oubliez pas de mettre un double support au second argument, sinon, il lèvera une erreur de dimension.

Ici, j'ajoute la matrice A

1 2 3
4 5 6

avec une rangée

7 8 9

même usage dans np.r_

A= [[1, 2, 3], [4, 5, 6]]
np.append(A, [[7, 8, 9]], axis=0)

    >> array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
#or 
np.r_[A,[[7,8,9]]]

Juste pour répondre à l'intérêt de quelqu'un, si vous souhaitez ajouter une colonne,

array = np.c_[A,np.zeros(#A's row size)]

en suivant ce que nous avons fait précédemment sur la matrice A, en y ajoutant une colonne

np.c_[A, [2,8]]

>> array([[1, 2, 3, 2],
          [4, 5, 6, 8]])

17voto

rbasham Points 171

Si aucun calcul n'est nécessaire après chaque ligne, il est beaucoup plus rapide d'ajouter des lignes en python, puis de les convertir en numpy. Voici des tests de temps en utilisant python 3.6 contre numpy 1.14, en ajoutant 100 lignes, une à la fois :

import numpy as np 
from time import perf_counter, sleep

def time_it():
    # Compare performance of two methods for adding rows to numpy array
    py_array = [[0, 1, 2], [0, 2, 0]]
    py_row = [4, 5, 6]
    numpy_array = np.array(py_array)
    numpy_row = np.array([4,5,6])
    n_loops = 100

    start_clock = perf_counter()
    for count in range(0, n_loops):
       numpy_array = np.vstack([numpy_array, numpy_row]) # 5.8 micros
    duration = perf_counter() - start_clock
    print('numpy 1.14 takes {:.3f} micros per row'.format(duration * 1e6 / n_loops))

    start_clock = perf_counter()
    for count in range(0, n_loops):
        py_array.append(py_row) # .15 micros
    numpy_array = np.array(py_array) # 43.9 micros       
    duration = perf_counter() - start_clock
    print('python 3.6 takes {:.3f} micros per row'.format(duration * 1e6 / n_loops))
    sleep(15)

#time_it() prints:

numpy 1.14 takes 5.971 micros per row
python 3.6 takes 0.694 micros per row

Ainsi, la solution simple à la question originale, qui date d'il y a sept ans, consiste à utiliser vstack() pour ajouter une nouvelle ligne après avoir converti la ligne en un tableau numpy. Mais une solution plus réaliste devrait prendre en compte les faibles performances de vstack dans ces circonstances. Si vous n'avez pas besoin d'exécuter une analyse de données sur le tableau après chaque ajout, il est préférable de mettre en mémoire tampon les nouvelles lignes dans une liste python de lignes (une liste de listes, en fait), et de les ajouter en groupe au tableau numpy en utilisant vstack() avant d'effectuer toute analyse de données.

10voto

cam Points 19

Vous pouvez également le faire :

newrow = [1,2,3]
A = numpy.concatenate((A,newrow))

2 votes

Hmmm. quand j'ai essayé cela, il a juste ajouté à la fin de A, plutôt que d'ajouter une nouvelle ligne comme OP l'a demandé.

13 votes

Probablement np.concatenate((A,newrow), axis=0)

3 votes

À partir de la version de numpy 1.12.1 (et dans Python 3), il semble que la tentative de concaténation d'un vecteur à une matrice soulève le problème suivant ValueError: all the input arrays must have same number of dimensions . On dirait qu'il veut que le vecteur soit explicitement remodelé en un vecteur colonne ou ligne avant de vouloir le concaténer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X