inicializar uma matriz numpy

129

Existe uma maneira de inicializar uma matriz numpy de uma forma e adicionar a ela? Vou explicar o que preciso com um exemplo de lista. Se eu quiser criar uma lista de objetos gerados em um loop, eu posso fazer:

a = []
for i in range(5):
    a.append(i)

Eu quero fazer algo semelhante com uma matriz numpy. Eu sei sobre vstack, concatenar etc. No entanto, parece que estes requerem duas matrizes numpy como entradas. O que eu preciso é:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

O big_arraydeve ter uma forma (10,4). Como fazer isso?


EDITAR:

Quero adicionar o seguinte esclarecimento. Estou ciente de que posso definir big_array = numpy.zeros((10,4))e preenchê-lo. No entanto, isso requer a especificação antecipada do tamanho do big_array. Eu sei o tamanho neste caso, mas e se eu não? Quando usamos a .appendfunção para estender a lista em python, não precisamos conhecer seu tamanho final com antecedência. Gostaria de saber se existe algo semelhante para criar uma matriz maior a partir de matrizes menores, começando com uma matriz vazia.

Curious2learn
fonte
Aliás sua primeira amostra de código pode ser escrito de forma limpa e sucintamente como uma compreensão da lista: [i for i in range(5)]. (Equivalentemente:, list(range(5))embora este seja um exemplo artificial.) #
Katriel
que solução funcionou para você? Eu estou tentando fazer algo semelhante, x = numpy.array()exatamente como faríamos com uma lista como y = []; mas não funcionou
Krazzy R

Respostas:

160

numpy.zeros

Retorne uma nova matriz de determinada forma e tipo, preenchida com zeros.

ou

numpy.ones

Retorne uma nova matriz de determinada forma e tipo, preenchida com outras.

ou

numpy.empty

Retorne uma nova matriz de determinada forma e tipo, sem inicializar entradas.


No entanto, a mentalidade em que construímos uma matriz anexando elementos a uma lista não é muito usada em numpy, porque é menos eficiente (os tipos de dados numpy estão muito mais próximos das matrizes C subjacentes). Em vez disso, você deve pré-alocar a matriz para o tamanho que precisa e, em seguida, preencha as linhas. Você pode usar numpy.appendse precisar, no entanto.

Katriel
fonte
2
Eu sei que posso definir big_array = numpy.zeros e preenchê-lo com as pequenas matrizes criadas. Isso, no entanto, exige que eu especifique o tamanho de big_array antecipadamente. Não existe nada como .append da função list onde eu não tenho o tamanho especificado com antecedência. Obrigado!
precisa
2
@ Curious2learn. Não, não há nada como acrescentar no Numpy. Existem funções que concatenam matrizes ou as empilham criando novas matrizes, mas não o fazem anexando. Isso ocorre pela maneira como as estruturas de dados são configuradas. As matrizes numpy são feitas para serem rápidas devido à capacidade de armazenar valores de forma mais compacta, mas precisam ter um tamanho fixo para obter essa velocidade. As listas Python são projetadas para serem mais flexíveis ao custo de velocidade e tamanho.
26710 Justin Peel
3
@Curious: bem, há um appendnumpy. Só que é menos eficiente não pré-alocar (nesse caso, muito menos eficiente, já que appendcopia toda a matriz toda vez), portanto, não é uma técnica padrão.
Katriel
1
E se apenas parte da np.emptymatriz for preenchida por valores? E os itens "vazios" restantes?
Lee
1
Se você só conhece sabe a largura (por exemplo necessário para np.concatenate()), você pode inicializar com: np.empty((0, some_width)). 0, então sua primeira matriz não será lixo.
NumesSanguis
40

A maneira como costumo fazer isso é criando uma lista regular, anexando minhas coisas a ela e, finalmente, transformando a lista em uma matriz numpy da seguinte maneira:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

é claro que seu objeto final ocupa o dobro do espaço na memória na etapa de criação, mas anexar na lista python é muito rápido, e a criação usando np.array () também.

mad7777
fonte
11
Esse não é o caminho a seguir, se você sabe o tamanho da matriz antes do tempo , no entanto ... acabo usando esse método frequentemente quando não sei o tamanho da matriz. Por exemplo, ao ler dados de um arquivo ou outro processo. Não é realmente tão horrível quanto pode parecer à primeira vista, já que python e numpy são bastante inteligentes.
travc
18

Introduzido no numpy 1.8:

numpy.full

Retorne uma nova matriz de determinada forma e tipo, preenchida com fill_value.

Exemplos:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])
Franck Dernoncourt
fonte
13

Análogo de matriz para o python

a = []
for i in range(5):
    a.append(i)

é:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)
Adobe
fonte
5
@ NicolasTJ: empty((0))inicializa uma matriz numpy.
Adobe
2
colchetes em np.empty ((0)) são redundantes.
Szymon Roziewski 19/02/19
7

numpy.fromiter() é o que você está procurando:

big_array = numpy.fromiter(xrange(5), dtype="int")

Também funciona com expressões geradoras, por exemplo:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Se você souber o tamanho da matriz com antecedência, poderá especificá-la com um argumento opcional 'count'.

Quant Metropolis
fonte
2
Na verdade, executei timeit e acho que o np.fromiter () pode ser mais lento que o np.array (). timeit ("np.array (i para i no xrange (100))", setup = "import numpy as np", número = 10000) -> 0,02539992332458496, versus timeit ("np.fromiter ((i para i no xrange ( 100)), dtipo = int)", setup = "import numpy como np", number = 10000) -> ,13351011276245117
hlin117
6

Você deseja evitar loops explícitos o máximo possível ao fazer a computação em matriz, pois isso reduz o ganho de velocidade dessa forma de computação. Existem várias maneiras de inicializar uma matriz numpy. Se você quiser preenchê-lo com zeros, faça o que o katrielalex disse:

big_array = numpy.zeros((10,4))

EDIT: Que tipo de sequência você está fazendo? Você deve verificar as diferentes funções numpy que criam matrizes, como numpy.linspace(start, stop, size)(número igualmente espaçado) ou numpy.arange(start, stop, inc). Onde possível, essas funções tornarão as matrizes substancialmente mais rápidas do que o mesmo trabalho em loops explícitos

Andreas Løve Selvik
fonte
5

Para o seu primeiro exemplo de matriz, use,

a = numpy.arange(5)

Para inicializar big_array, use

big_array = numpy.zeros((10,4))

Isso pressupõe que você deseja inicializar com zeros, o que é bastante típico, mas existem muitas outras maneiras de inicializar uma matriz em numpy .

Edit: Se você não sabe o tamanho de big_array antecipadamente, geralmente é melhor primeiro criar uma lista Python usando o append e, quando você tiver tudo reunido na lista, converta essa lista em uma matriz numpy usando numpy.array(mylist). A razão para isso é que as listas devem crescer muito eficientemente e rapidamente, enquanto que o numpy.concatenate seria muito ineficiente, pois matrizes numpy não mudam de tamanho facilmente. Porém, quando tudo é coletado em uma lista e você sabe o tamanho final da matriz, uma matriz numpy pode ser construída com eficiência.

tom10
fonte
5

Para inicializar uma matriz numpy com uma matriz específica:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

resultado:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]
edW
fonte
3

Sempre que você estiver na seguinte situação:

a = []
for i in range(5):
    a.append(i)

e você deseja algo semelhante em numpy, várias respostas anteriores apontaram maneiras de fazer isso, mas como @katrielalex apontou, esses métodos não são eficientes. A maneira eficiente de fazer isso é criar uma lista longa e remodelá-la da maneira que desejar depois de ter uma lista longa. Por exemplo, digamos que estou lendo algumas linhas de um arquivo e cada linha tem uma lista de números e quero criar uma matriz numpy de forma (número de linhas lidas, comprimento do vetor em cada linha). Aqui está como eu faria isso com mais eficiência:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array
Heapify
fonte
2

Percebo que isso é um pouco tarde, mas não notei nenhuma das outras respostas mencionando a indexação na matriz vazia:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

Dessa forma, você pré-aloca toda a matriz de resultados numpy.emptye preenche as linhas à medida que utiliza a atribuição indexada.

É perfeitamente seguro pré-alocar em emptyvez do zerosexemplo que você deu, pois você garante que toda a matriz será preenchida com os pedaços que você gerar.

Físico louco
fonte
2

Eu sugiro definir a forma primeiro. Em seguida, itere sobre ele para inserir valores.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])
GT GT
fonte
1

Talvez algo assim atenda às suas necessidades.

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Que produz a seguinte saída

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]

fonte