Як створити порожній масив / матрицю в NumPy?


311

Я не можу зрозуміти, як використовувати масив або матрицю так, як зазвичай я використовую список. Я хочу створити порожній масив (або матрицю), а потім додати до нього один стовпчик (або рядок) за раз.

На даний момент єдиний спосіб, коли я можу це зробити, це такий:

mat = None
for col in columns:
    if mat is None:
        mat = col
    else:
        mat = hstack((mat, col))

Тоді якби це був список, я б зробив щось подібне:

list = []
for item in data:
    list.append(item)

Чи є спосіб використовувати таке позначення для масивів чи матриць NumPy ?

Відповіді:


441

У вас неправильна ментальна модель для ефективного використання NumPy. Масиви NumPy зберігаються в суміжних блоках пам'яті. Якщо ви хочете додати рядки або стовпці до існуючого масиву, весь масив потрібно скопіювати в новий блок пам'яті, створивши прогалини для нових елементів, які потрібно зберігати. Це дуже неефективно, якщо робити це неодноразово для створення масиву.

У разі додавання рядків найкраще створити масив, який буде таким же великим, як з часом буде набір даних, а потім додати до нього дані по черзі:

>>> import numpy
>>> a = numpy.zeros(shape=(5,2))
>>> a
array([[ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])
>>> a[0] = [1,2]
>>> a[1] = [2,3]
>>> a
array([[ 1.,  2.],
   [ 2.,  3.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])

123
Існує також numpy.empty (), якщо вам не потрібно нульовий масив.
січень

21
Яка користь від використання порожнього () над нулями ()?
Зак

45
що якщо ви збираєтесь ініціалізувати їх зі своїми даними, ви економите витрати на їх обнулення.
marcorossi

16
@maracorossi значить, у клітинках .empty()можна знайти випадкові значення, але масив створюється швидше, ніж, наприклад, за допомогою .zeros()?
користувач3085931

6
@ user3085931 так!
Натан

98

Масив NumPy - це зовсім інша структура даних зі списку і призначена для використання по-різному. Ваше використання hstackпотенційно є дуже неефективним ... щоразу, коли ви викликаєте його, всі дані з існуючого масиву копіюються в новий. (У appendфункції буде та сама проблема.) Якщо ви хочете зібрати свою матрицю по одному стовпчику за раз, вам, можливо, найкраще буде зберігати її в списку до її завершення, і лише потім перетворювати її в масив.

напр


mylist = []
for item in data:
    mylist.append(item)
mat = numpy.array(mylist)

itemможе бути список, масив або будь-який ітерабельний, якщо кожен itemмає однакову кількість елементів.
У цьому конкретному випадку ( dataякийсь ітерабельний вміст стовпців матриці) ви можете просто використовувати


mat = numpy.array(data)

(Також зауважте, що використання listяк імені змінної, ймовірно, не є хорошою практикою, оскільки воно маскує вбудований тип під цим іменем, що може призвести до помилок.)

Редагувати:

Якщо ви чомусь дійсно хочете створити порожній масив, ви можете просто скористатися numpy.array([]), але це рідко корисно!


1
Чи принципово відрізняються нумерові масиви / матриці від Matlab?
levesque

1
Якщо з якоїсь - то причини вам необхідно визначити порожній масив, але з фіксованою шириною (наприклад np.concatenate()), ви можете використовувати: np.empty((0, some_width)). 0, тож ваш перший масив не буде сміттям.
NumesSanguis

56

Щоб створити порожній багатовимірний масив у NumPy (наприклад, 2D-масив m*nдля зберігання вашої матриці), якщо ви не знаєте, mскільки рядків ви додасте, і не хвилюєтесь обчислювальною вартістю Стівена Сіммонса (а саме відновлення збірки масив на кожному Append), ви можете стиснути до 0 вимір , до якого ви хочете додати до: X = np.empty(shape=[0, n]).

Таким чином ви можете використовувати, наприклад (тут, як m = 5ми вважаємо, що ми не знали при створенні порожньої матриці, і n = 2):

import numpy as np

n = 2
X = np.empty(shape=[0, n])

for i in range(5):
    for j  in range(2):
        X = np.append(X, [[i, j]], axis=0)

print X

що дасть вам:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]

1
Це має бути відповіддю на поставлене запитання ОП, у випадку використання, коли ви не знаєте #rows заздалегідь, або хочете розібратися зі справою, що є 0 рядків
Spcogg другий

26

Я багато розглядав це, тому що мені потрібно було використовувати numpy.array як набір в одному з моїх шкільних проектів, і мені потрібно було ініціалізувати порожнє ... Я не знайшов відповідної відповіді тут на Stack Overflow, тому я почав щось малює.

# Initialize your variable as an empty list first
In [32]: x=[]
# and now cast it as a numpy ndarray
In [33]: x=np.array(x)

Результатом буде:

In [34]: x
Out[34]: array([], dtype=float64)

Тому ви можете безпосередньо ініціалізувати масив np таким чином:

In [36]: x= np.array([], dtype=np.float64)

Я сподіваюся, що це допомагає.


Це не працює для масивів, як у питанні, але може бути корисним для векторів.
divenex

a=np.array([])Здається, за замовчуваннямfloat64
P i

7

Ви можете використовувати функцію додавання. Для рядків:

>>> from numpy import *
>>> a = array([10,20,30])
>>> append(a, [[1,2,3]], axis=0)
array([[10, 20, 30],      
       [1, 2, 3]])

Для стовпців:

>>> append(a, [[15],[15]], axis=1)
array([[10, 20, 30, 15],      
       [1, 2, 3, 15]])

EDIT
Звичайно, як зазначено в інших відповідях, якщо ви не робите певної обробки (наприклад, інверсії) на матриці / масиві КОЖНО, коли ви щось додаєте до неї, я б просто створив список, додав би його, а потім перетворив його на масив.


3

Якщо ви абсолютно не знаєте кінцевий розмір масиву, ви можете збільшити розмір масиву таким чином:

my_arr = numpy.zeros((0,5))
for i in range(3):
    my_arr=numpy.concatenate( ( my_arr, numpy.ones((1,5)) ) )
print(my_arr)

[[ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]]
  • Зверніть увагу на 0перший рядок.
  • numpy.appendінший варіант. Це дзвонить numpy.concatenate.

3

Ви можете застосувати його для створення будь-якого типу масиву, як нулі:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]

4
Якщо ви хочете зробити це в чистому a= [0] * 5
пітоні

3

Ось декілька варіантів, щоб зробити numpys схожішими на Списки

np_arr = np.array([])
np_arr = np.append(np_arr , 2)
np_arr = np.append(np_arr , 24)
print(np_arr)

ВИХІД: масив ([2., 24.])


2

Залежно від того, для чого ви це використовуєте, вам може знадобитися вказати тип даних (див. 'Dtype' ).

Наприклад, для створення 2D масиву 8-бітних значень (підходить для використання в якості монохромного зображення):

myarray = numpy.empty(shape=(H,W),dtype='u1')

Для зображення RGB включайте кількість кольорових каналів у формі: shape=(H,W,3)

Ви також можете розглянути можливість нульової ініціалізації, numpy.zerosа не використовувати numpy.empty. Дивіться примітку тут .


1

Я думаю, що ви хочете обробляти більшу частину роботи зі списками, а потім використовувати результат як матрицю. Можливо, це спосіб;

ur_list = []
for col in columns:
    ur_list.append(list(col))

mat = np.matrix(ur_list)

1

Я думаю, ви можете створити порожній масив типу:

>>> import numpy as np
>>> empty_array= np.zeros(0)
>>> empty_array
array([], dtype=float64)
>>> empty_array.shape
(0,)

Цей формат корисний, коли ви хочете додати numpy масив у циклі.


0

Для створення порожнього масиву NumPy без визначення його форми є спосіб:

1.

arr = np.array([]) 

кращий. тому що ви знаєте, що ви будете використовувати це як немічний.

2.

arr = []
# and use it as numpy. append to it or etc..

NumPy перетворює це в тип np.ndarray згодом, без зайвих [] dimionsion.

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