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 dans X répond à une condition spécifique.
Les tableaux Numpy n'ont pas de méthode 'append' comme celle des listes, ou il semble.
Si A et X étaient des listes, je ferais simplement:
for i in X:
if i[0] < 3:
A.append(i)
Y a-t-il un moyen numpythonic de faire l'équivalent?
Merci, S ; -)
8 réponses
Qu'est-Ce que X
? Si c'est un tableau 2D, Comment Pouvez-vous alors comparer sa ligne à un nombre: i < 3
?
Modifier après le commentaire D'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
:
A = vstack((A, X[X[:,0] < 3]))
# returns:
array([[0, 1, 2],
[0, 2, 0],
[0, 1, 2],
[1, 2, 0],
[2, 1, 2]])
Eh bien, vous pouvez le faire:
newrow = [1,2,3]
A = numpy.vstack([A, newrow])
Comme cette question a été 7 ans auparavant, dans la dernière version que j'utilise est 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 crochet au deuxième argument, sinon, il va soulever une erreur de dimension. même utilisation dans np.r_
np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
>> array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Juste pour quelqu'un est interessé, si vous souhaitez ajouter une colonne,
array = np.c_[A,np.zeros(#A's row size)]
Vous pouvez également faire ceci:
newrow = [1,2,3]
A = numpy.concatenate((A,newrow))
Si vous pouvez faire la construction en une seule opération, alors quelque chose comme la réponse vstack-with-fancy-indexing est une bonne approche. Mais si votre condition est plus compliquée ou si vos lignes arrivent à la volée, vous voudrez peut-être développer le tableau. En fait, la façon numpythonic de faire quelque chose comme ça - développer dynamiquement un tableau - est de développer dynamiquement une liste:
A = np.array([[1,2,3],[4,5,6]])
Alist = [r for r in A]
for i in range(100):
newrow = np.arange(3)+i
if i%5:
Alist.append(newrow)
A = np.array(Alist)
del Alist
Les listes Sont hautement optimisées pour ce type de modèle d'accès; vous n'avez pas d'indexation multidimensionnelle numpy pratique bien que sous forme de liste, mais aussi longtemps que vous ajoutez, il est difficile de faire mieux qu'une liste de tableaux de lignes.
Vous pouvez utiliser numpy.append()
pour ajouter une ligne au tableau numpty et remodeler une matrice plus tard.
import numpy as np
a = np.array([1,2])
a = np.append(a, [3,4])
print a
# [1,2,3,4]
# in your example
A = [1,2]
for row in X:
A = np.append(A, row)
J'utilise ' np.vstack ' qui est plus rapide, EX:
import numpy as np
input_array=np.array([1,2,3])
new_row= np.array([4,5,6])
new_array=np.vstack([input_array, new_row])
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 synchronisation utilisant Python 3.6 vs. numpy 1.14, en ajoutant 100 lignes, une à la fois:
import numpy as py
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
Donc, la solution simple à la question originale, d'il y a sept ans, est d'utiliser vstack() pour ajouter une nouvelle ligne après avoir converti la ligne en un tableau numpy. Mais une solution plus réaliste devrait tenir compte des mauvaises performances de vstack dans ces circonstances. Si vous n'avez pas besoin de exécutez l'analyse des 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 de lignes python (une liste de listes, vraiment), et de les ajouter en tant que groupe au tableau numpy en utilisant vstack() avant de faire une analyse de données.