Como crio uma matriz / matriz vazia no NumPy?

311

Não consigo descobrir como usar uma matriz ou matriz da maneira que normalmente usaria uma lista. Quero criar uma matriz (ou matriz) vazia e, em seguida, adicionar uma coluna (ou linha) a ela por vez.

No momento, a única maneira de encontrar isso é:

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

Considerando que, se fosse uma lista, eu faria algo assim:

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

Existe uma maneira de usar esse tipo de notação para matrizes ou matrizes NumPy ?

Ben
fonte

Respostas:

441

Você tem o modelo mental errado para usar o NumPy com eficiência. As matrizes NumPy são armazenadas em blocos contíguos de memória. Se você deseja adicionar linhas ou colunas a uma matriz existente, toda a matriz precisa ser copiada para um novo bloco de memória, criando espaços para os novos elementos a serem armazenados. Isso é muito ineficiente se feito repetidamente para criar uma matriz.

No caso de adicionar linhas, sua melhor aposta é criar uma matriz do tamanho que o seu conjunto de dados acabará sendo e, em seguida, adicionar dados a ela linha por linha:

>>> 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.]])
Stephen Simmons
fonte
123
Também existe numpy.empty () se você não precisar zerar a matriz.
janneb
21
Qual é o benefício de usar vazio () sobre zeros ()?
Zach
45
que, se você quiser inicializá-lo com seus dados imediatamente, economize o custo de zerá-lo.
Marcorossi
16
@maracorossi .empty()significa que é possível encontrar valores aleatórios nas células, mas a matriz é criada mais rapidamente do que, por exemplo, com .zeros()?
user3085931
6
@ user3085931 sim!
Nathan
98

Uma matriz NumPy é uma estrutura de dados muito diferente de uma lista e foi projetada para ser usada de maneiras diferentes. Seu uso hstacké potencialmente muito ineficiente ... toda vez que você o chama, todos os dados na matriz existente são copiados para uma nova. (A appendfunção terá o mesmo problema.) Se você deseja construir sua matriz uma coluna por vez, é melhor mantê-la em uma lista até que ela termine e depois convertê-la em uma matriz.

por exemplo


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

itempode ser uma lista, uma matriz ou qualquer iterável, desde que cada um itemtenha o mesmo número de elementos.
Nesse caso em particular ( dataé algo iterável manter as colunas da matriz), você pode simplesmente usar


mat = numpy.array(data)

(Observe também que o uso listcomo nome de variável provavelmente não é uma boa prática, pois mascara o tipo interno com esse nome, o que pode levar a erros.)

EDITAR:

Se, por algum motivo, você realmente deseja criar uma matriz vazia, basta usar numpy.array([]), mas isso raramente é útil!

Greg Ball
fonte
1
As matrizes / matrizes numpy são fundamentalmente diferentes das matrizes do Matlab?
Levesque
1
Se por algum motivo você precisa definir uma matriz vazia, mas com largura fixa (por exemplo np.concatenate()), você pode usar: np.empty((0, some_width)). 0, então sua primeira matriz não será lixo.
NumesSanguis
56

Para criar uma matriz multidimensional vazia no NumPy (por exemplo, uma matriz 2D m*npara armazenar sua matriz), caso você não saiba mquantas linhas você acrescentará e não se importe com o custo computacional mencionado por Stephen Simmons (ou seja, reconstruir o variedade em cada append), você pode espremer para 0 a dimensão para a qual você deseja anexar: X = np.empty(shape=[0, n]).

Dessa forma, você pode usar, por exemplo (aqui, m = 5que assumimos que não sabíamos ao criar a matriz vazia, e 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

o que lhe dará:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]
Franck Dernoncourt
fonte
1
Essa deve ser a resposta para a pergunta do OP, para o caso de uso em que você não conhece #rows com antecedência ou deseja lidar com o caso de que existem 0 linhas
Spcogg no segundo dia 15/08/19
26

Eu olhei bastante para isso porque precisava usar um numpy.array como um conjunto em um dos meus projetos de escola e precisava ser inicializado vazio ... Não encontrei nenhuma resposta relevante aqui no Stack Overflow, então comecei rabiscando algo.

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

O resultado será:

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

Portanto, você pode inicializar diretamente uma matriz np da seguinte maneira:

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

Eu espero que isso ajude.

Andrei Paga
fonte
Isso não funciona para matrizes, como na pergunta, mas pode ser útil para vetores.
divenex
a=np.array([])parece padrão parafloat64
P i
7

Você pode usar a função de acréscimo. Para linhas:

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

Para colunas:

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

EDIT
Obviamente, como mencionado em outras respostas, a menos que você esteja fazendo algum processamento (por exemplo, inversão) na matriz / matriz Toda vez que você anexa algo a ele, eu apenas criava uma lista, anexava a ele e depois o convertia em um array.

Il-Bhima
fonte
3

Se você absolutamente não sabe o tamanho final da matriz, pode aumentar o tamanho da matriz assim:

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.]]
  • Observe o 0na primeira linha.
  • numpy.appendé outra opção. Isso chama numpy.concatenate.
cyborg
fonte
3

Você pode aplicá-lo para criar qualquer tipo de matriz, como zeros:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]
Ali G
fonte
4
Se você quiser fazer isso em python puro, a= [0] * 5é a solução simples
Makers_F
3

Aqui estão algumas soluções alternativas para tornar os numpys mais parecidos com Listas

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

SAÍDA: matriz ([2., 24.])

Darius
fonte
2

Dependendo do motivo pelo qual você está usando isso, pode ser necessário especificar o tipo de dados (consulte 'dtype' ).

Por exemplo, para criar uma matriz 2D de valores de 8 bits (adequado para uso como uma imagem monocromática):

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

Para uma imagem RGB, inclua o número de canais de cores na forma: shape=(H,W,3)

Você também pode considerar inicializar com zero em numpy.zerosvez de usar numpy.empty. Veja a nota aqui .

nobar
fonte
1

Eu acho que você deseja lidar com a maior parte do trabalho com listas e depois usar o resultado como uma matriz. Talvez seja esse o caminho;

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

mat = np.matrix(ur_list)
runo
fonte
1

Eu acho que você pode criar uma matriz numpy vazia como:

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

Este formato é útil quando você deseja acrescentar uma matriz numpy no loop.

veeresh d
fonte
0

Para criar uma matriz NumPy vazia sem definir sua forma, existe uma maneira de:

1

arr = np.array([]) 

preferido. porque você sabe que vai usar isso como numpy.

2)

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

NumPy converte isso no tipo np.ndarray posteriormente, sem extra [] dimionsion.

Pedram
fonte
0

Talvez o que você está procurando seja algo como isto:

x=np.array(0)

Dessa forma, você pode criar uma matriz sem nenhum elemento. É semelhante a:

x=[]

Dessa forma, você poderá acrescentar novos elementos à sua matriz com antecedência.

Edgar Duarte
fonte