Numpy - додайте рядок до масиву


161

Як додавати рядки до масиву numpy?

У мене масив A:

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

Я хочу додати рядки до цього масиву з іншого масиву X, якщо перший елемент кожного рядка в X відповідає певній умові.

Numpy масиви не мають методу "додати", як у списках, або так здається.

Якби A і X були списками, я б просто робив:

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

Чи є нумептонічний спосіб зробити еквівалент?

Спасибі, S ;-)


Відповіді:


120

Що таке X? Якщо це 2D-масив, то як ви можете порівняти його рядок із числом i < 3:?

EDIT після коментаря ОП:

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

додати до Aвсіх рядків, Xзвідки перший елемент < 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
Вибачте гарний момент! Припустимо 2D масив, з якого перший елемент кожного ряду повинен відповідати умові. Я це відредагую. Дякую, S ;-)
Даррен Дж. Фіцпатрік

2
@ DarrenJ.Fitzpatrick Майте на увазі, що, виконуючи цей тип маніпуляцій, ви працюєте проти хорошої роботи, Numpy робить попередньо виділення пам'яті для наявного масиву A. Очевидно, що для такої невеликої проблеми, як у цій відповіді, це не проблема, але вона може бути більш тривожною для великих даних.
dtlussier

166

добре ти можеш це зробити:

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

2
@Kris Чому це застаріле? Я нічого не бачу в документах
Георгій

1
@Georgy Якщо чесно, я не знаю. Я тут шукав відповіді так само, як і ви :-). Не можу зараз пригадати, чому я написав вище коментар. Я, мабуть, бачив у документах його застаріле. Але дивлячись на документи зараз ... це не так. Можливо, вони знецінили його, потім знову передумали і вирішили, що буде занадто дратує надто багато людей, щоб зневажити та видалити його?
Кріс

32

Оскільки це питання було 7 років тому, в останній версії, яку я використовую, є numpy версія 1.13, і python3, я роблю те саме, що додаю рядок до матриці, не забудьте поставити подвійну дужку до другого аргументу, інакше це призведе до помилки розмірності.

Тут я додаю на матрицю А

1 2 3
4 5 6

з рядом

7 8 9

таке ж використання в 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]]]

Просто, щоб хтось заступався, якщо ви хочете додати стовпець,

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

слідкуючи за тим, що ми робили раніше на матриці A, додаючи до неї стовпчик

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

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

10

Ви також можете зробити це:

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

2
хммм. коли я спробував це, він просто додав до кінця A, а не додав новий рядок, як вимагав ОП.
Todd Curry

13
ймовірноnp.concatenate((A,newrow), axis=0)
Костянтинос Родітакіс

3
Як і у версії numpy 1.12.1(і в Python 3), схоже, намагання об'єднати вектор у матрицю піднімає ValueError: all the input arrays must have same number of dimensions. Схоже, він хоче, щоб вектор було чітко перетворено в вектор стовпця або рядка, перш ніж він готовий об'єднати його.
МРУЛ

3
@MRule можна виправити, використовуючи подвійні квадратні дужки , як у відповідь від @Flora PJ Li stackoverflow.com/a/47845065/1410035 . newrow = [[1,2,3]]
Том Салееба

10

Якщо після кожного ряду не потрібні розрахунки, набагато швидше додати рядки в python, а потім перетворити на numpy. Ось терміни тестування з використанням python 3.6 проти numpy 1.14, додаючи 100 рядків, по одному:

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

Отже, найпростішим рішенням оригінального запитання, починаючи з семи років тому, є використання vstack () для додавання нового рядка після перетворення рядка в numpy масив. Але більш реалістичним рішенням слід вважати низьку ефективність компанії vstack за тих обставин. Якщо вам не потрібно запускати аналіз даних у масиві після кожного додавання, краще буферизувати нові рядки до списку рядків python (насправді список списків) та додати їх як групу до масиву numpy використання vstack () перед тим, як робити будь-який аналіз даних.


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

Якщо ви можете виконати конструкцію за одну операцію, то щось на кшталт відповіді vstack-with-fancy-indexes - це прекрасний підхід. Але якщо ваш стан складніший або ваші ряди приходять на льоту, можливо, ви захочете виростити масив. Насправді нумептичний спосіб зробити щось подібне - динамічно рости масив - це динамічно рости список:

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

Списки оптимізовані для такого типу доступу; у вас немає зручного багатовимірного індексування нумерації, перебуваючи у формі списку, але поки ви додаєте, це важко зробити краще, ніж список масивів рядків.


3

Я використовую 'np.vstack', який швидше, 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

Ви можете використовувати numpy.append()для додавання рядка до нульового масиву та змінити форму в матрицю пізніше.

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.