Comment ajoute-t-on 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 n'ont pas de méthode 'append' comme celle des listes, semble-t-il.
Si A et X étaient des listes, je ferais simplement:
for i in X:
if i[0] < 3:
A.append(i)
Existe-t-il un moyen numpythonic de faire l’équivalent?
Merci, S ;-)
Qu'est-ce que X
? Si c'est un tableau 2D, comment pouvez-vous alors comparer sa ligne à un nombre: i < 3
?
EDIT après le commentaire de 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]])
bien tu peux faire ça:
newrow = [1,2,3]
A = numpy.vstack([A, newrow])
Vous pouvez aussi faire ceci:
newrow = [1,2,3]
A = numpy.concatenate((A,newrow))
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
Ainsi, la solution simple à la question initiale, posée il y a sept ans, consiste à utiliser vstack () pour ajouter une nouvelle ligne après l'avoir convertie en tableau numpy. Mais une solution plus réaliste devrait prendre en compte les mauvaises performances de vstack dans ces circonstances. Si vous n'avez pas besoin d'exécuter l'analyse de données sur le tableau après chaque addition, il est préférable de mettre en tampon les nouvelles lignes dans une liste de lignes python (une liste de listes, en réalité), et de les ajouter en tant que groupe au tableau numpy. en utilisant vstack () avant toute analyse de données.
Si vous pouvez effectuer la construction en une seule opération, une solution telle que la réponse vstack-with-fancy-indexing constitue une solution de choix. Mais si votre condition est plus compliquée ou si vos lignes entrent à la volée, vous souhaiterez peut-être agrandir le tableau. En fait, la manière numpythonique de faire quelque chose comme ceci - agrandir dynamiquement un tableau - consiste à agrandir 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 ne disposez pas d'indexation multidimensionnelle numpy pratique lorsque vous êtes sous forme de liste, mais il est difficile de faire mieux qu'une liste de tableaux de rangées.
Vous pouvez utiliser numpy.append()
pour ajouter une ligne à un tableau numpty et le remodeler ultérieurement à une matrice.
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])
array_ = np.array([[1,2,3]])
add_row = np.array([[4,5,6]])
array_ = np.concatenate((array_, add_row), axis=0)