Як створити порожній масив / матрицю в 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.