Как создать пустой массив / матрицу в NumPy?

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

на данный момент единственный способ, которым я могу это сделать, это:

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)

есть ли способ использовать такие обозначения для включает в себя массивы или матрицы?

9 ответов


у вас неправильная ментальная модель для эффективного использования 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.]])

массив NumPy-это совсем другая структура данных из списка и предназначен для использования по-разному. Использование hstack потенциально очень неэффективно... каждый раз, когда вы вызываете его, все данные в существующем массиве копируются в новый. (The append функция будет иметь ту же проблему.) Если вы хотите создать свою матрицу по одному столбцу за раз, вам лучше всего сохранить ее в списке до тех пор, пока она не будет завершена, и только затем преобразовать ее в матрица.

например


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

item может быть списком, массивом или любой итерацией, если как каждый item имеет такое же количество элементов.
В данном конкретном случае (data какая-холдинг повторяемое столбцы матрицы), вы можете просто использовать


mat = numpy.array(data)

(Также обратите внимание, что использование list поскольку имя переменной, вероятно, не является хорошей практикой, поскольку оно маскирует встроенный тип этим именем, что может привести к ошибкам.)

EDIT:

если по некоторым причинам вы действительно хотите создать пустой массив, вы можете просто использовать numpy.array([]), но это редко!


для создания пустого многомерного массива в NumPy (например, 2D array m*n для хранения вашей матрицы), если вы не знаете m сколько строк вы добавите и не заботитесь о вычислительной стоимости, упомянутой Стивеном Симмонсом (а именно, перестроение массива в каждом добавлении), вы можете сжать до 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.]]

Я много смотрел на это, потому что мне нужно было использовать numpy.массив как набор в одном из моих проектов, и я должен быть инициализирован пустым... Я не нашел подходящего ответа здесь на переполнение стека, поэтому я начал что-то рисовать.

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

надеюсь, это поможет.


Вы можете использовать функцию append. Для строк:

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

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


если вы абсолютно не знаете окончательный размер массива, вы можете увеличить размер массива следующим образом:

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.

вы можете применить его для построения любого массива, например нулей:

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

в зависимости от того, для чего вы это используете, вам может потребоваться указать тип данных (см. 'dtype').

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

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

для изображения RGB включите количество цветовых каналов в форме:shape=(H,W,3)

вы также можете рассмотреть возможность нулевой инициализации с помощью numpy.zeros вместо numpy.empty. См. Примечание здесь.


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

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

mat = np.matrix(ur_list)