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 ;-)

Darren J. Fitzpatrick
źródło
Zobacz także stackoverflow.com/questions/8486294/…
Thomas Ahle

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]])
eumiro
źródło
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])
jknair
źródło
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]])
Flora PJ Li
źródło
10

Możesz też to zrobić:

newrow = [1,2,3]
A = numpy.concatenate((A,newrow))
krzywka
źródło
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.

rbasham
źródło
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)
naman1994
źródło
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.

user2475529
źródło
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])
RAno
źródło
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)
Charles Chow
źródło