Numpy - dodaj wiersz do tablicy


161

Jak dodać wiersze do tablicy numpy?

Mam tablicę A:

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

Chciałbym dodać wiersze do tej tablicy z innej tablicy X, jeśli pierwszy element każdego wiersza w X spełnia określony warunek.

Tablice Numpy nie mają metody „dołączania”, takiej jak lista, a przynajmniej tak się wydaje.

Gdyby A i X były listami, zrobiłbym tylko:

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

Czy istnieje numpytoniczny sposób na zrobienie odpowiednika?

Dzięki, S ;-)


Odpowiedzi:


120

Co to jest X? Jeśli jest to tablica 2D, w jaki sposób możesz porównać jej wiersz z liczbą i < 3:?

EDYCJA po komentarzu OP:

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

dodaj do Awszystkich wierszy, od Xktórych pierwszy element < 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
Przepraszam słuszna uwaga! Załóżmy, że tablica 2D, w której pierwszy element każdego wiersza musi spełniać warunek. Zmienię to. Dzięki, S ;-)
Darren J. Fitzpatrick

2
@ DarrenJ.Fitzpatrick Pamiętaj, że wykonując tego typu manipulacje, pracujesz przeciwko dobrej pracy, jaką Numpy wykonuje przy wstępnym przydzielaniu pamięci dla istniejącej tablicy A. Oczywiście w przypadku małego problemu, takiego jak w tej odpowiedzi, nie stanowi to problemu, ale może być bardziej kłopotliwe w przypadku dużych danych.
dtlussier

166

cóż, możesz to zrobić:

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

2
@Kris Dlaczego jest przestarzały? Nic nie widzę w dokumentach
Georgy

1
@Georgy Szczerze mówiąc, nie wiem. Szukałem tutaj odpowiedzi tak samo jak Ty :-). Nie pamiętam teraz, dlaczego napisałem powyższy komentarz. Musiałem zobaczyć w dokumentach, że jest przestarzały. Ale patrząc teraz na dokumentację ... nie mówi tego. Czy to możliwe, że wycofali go, a potem ponownie zmienili zdanie i zdecydowali, że wycofanie go i usunięcie byłoby zbyt irytujące dla zbyt wielu ludzi?
Kris

32

Ponieważ to pytanie było 7 lat wcześniej, w najnowszej wersji, z której korzystam, to numpy w wersji 1.13 i python3, robię to samo z dodaniem wiersza do macierzy, pamiętaj, aby umieścić podwójny nawias na drugim argumencie, w przeciwnym razie spowoduje to błąd wymiaru.

Tutaj dodam macierz A

1 2 3
4 5 6

z rzędem

7 8 9

to samo użycie w 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]]]

Tylko dla kogoś zainteresowanego, jeśli chcesz dodać kolumnę,

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

postępując zgodnie z tym, co zrobiliśmy wcześniej na macierzy A, dodając do niej kolumnę

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

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

10

Możesz też to zrobić:

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

2
hmmm. kiedy próbowałem tego, po prostu dodałem na koniec A, zamiast dodawać nowy wiersz zgodnie z żądaniem OP.
Todd Curry,

13
prawdopodobnienp.concatenate((A,newrow), axis=0)
Konstantinos Roditakis

3
Od wersji numpy 1.12.1(iw Pythonie 3) wydaje się, że próba połączenia wektora z macierzą podnosi ValueError: all the input arrays must have same number of dimensions. Wygląda na to, że chce, aby wektor został jawnie przekształcony w wektor kolumnowy lub wierszowy, zanim będzie chciał go połączyć.
MRule

3
@MRule możesz to naprawić, używając podwójnych nawiasów kwadratowych, zgodnie z odpowiedzią z @Flora PJ Li stackoverflow.com/a/47845065/1410035 . newrow = [[1,2,3]]
Tom Saleeba

10

Jeśli po każdym wierszu nie są potrzebne żadne obliczenia, znacznie szybciej jest dodać wiersze w Pythonie, a następnie przekonwertować je na numpy. Oto testy czasu przy użyciu Pythona 3.6 w porównaniu z Numpy 1.14, dodając 100 wierszy, po jednym na raz:

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

Zatem prostym rozwiązaniem pierwotnego pytania sprzed siedmiu lat jest użycie metody vstack () do dodania nowego wiersza po konwersji wiersza na tablicę numpy. Ale bardziej realistyczne rozwiązanie powinno uwzględniać słabą wydajność vstack w takich okolicznościach. Jeśli nie potrzebujesz przeprowadzać analizy danych na tablicy po każdym dodaniu, lepiej jest buforować nowe wiersze do listy wierszy w Pythonie (tak naprawdę to lista list) i dodawać je jako grupę do tablicy numpy używając vstack () przed wykonaniem jakiejkolwiek analizy danych.


5
import numpy as np
array_ = np.array([[1,2,3]])
add_row = np.array([[4,5,6]])

array_ = np.concatenate((array_, add_row), axis=0)

3

Jeśli możesz wykonać konstrukcję w jednej operacji, to coś w rodzaju vstack-with-fantazy-indexing jest dobrym podejściem. Ale jeśli twój stan jest bardziej skomplikowany lub twoje wiersze pojawiają się w locie, możesz chcieć powiększyć tablicę. W rzeczywistości numpytonicznym sposobem zrobienia czegoś takiego - dynamicznego powiększania tablicy - jest dynamiczne powiększanie listy:

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

Listy są wysoce zoptymalizowane pod kątem tego rodzaju wzorca dostępu; nie masz wygodnego indeksowania wielowymiarowego numpy w formie listy, ale dopóki dodajesz, trudno jest zrobić coś lepszego niż lista tablic wierszy.


3

Używam 'np.vstack', który jest szybszy, 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])

2

Możesz użyć, numpy.append()aby dołączyć wiersz do tablicy numpty i zmienić kształt do macierzy później.

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.