Exibir em uma matriz numpy?

90

Eu tenho uma numpymatriz 2D . Existe uma maneira de criar uma exibição nele que inclua as primeiras klinhas e todas as colunas?

O objetivo é evitar copiar os dados subjacentes (a matriz é tão grande que fazer cópias parciais não é viável).

NPE
fonte

Respostas:

226

Claro, apenas indexe como faria normalmente. Por exemplo, y = x[:k, :] isso retornará uma visão do array original. Nenhum dado será copiado e quaisquer atualizações feitas em yserão refletidas em xe vice-versa.


Editar:

Normalmente trabalho com arrays 3D de mais de 10 GB de uint8, então me preocupo muito com isso ... O Numpy pode ser muito eficiente no gerenciamento de memória se você manter algumas coisas em mente. Aqui estão algumas dicas para evitar fazer cópias de matrizes na memória:

Use +=, -=, *=, etc, para evitar fazer uma cópia da matriz. Por exemplo, x += 10irá modificar o array no local, enquanto x = x + 10fará uma cópia e o modificará. (também, dê uma olhada em numexpr )

Se você quiser fazer uma cópia com x = x + 10, esteja ciente de que x = x + 10.0fará o xup-cast automaticamente para uma matriz de ponto flutuante, se ainda não foi. No entanto, x += 10.0onde xé uma matriz de inteiros, fará com que o 10.0seja convertido para um int com a mesma precisão da matriz.

Além disso, muitas funções numpy usam um outparâmetro, portanto, você pode fazer coisas como np.abs(x, x)obter o valor absoluto de xno local.


Como uma segunda edição, aqui estão mais algumas dicas sobre visualizações vs. cópias com matrizes numerosas:

Ao contrário das listas python, y = x[:]não retorna uma cópia, ele retorna uma visualização. Se você quiser uma cópia (o que, é claro, dobrará a quantidade de memória que você está usando), usey = x.copy()

Freqüentemente, você ouvirá sobre "indexação sofisticada" de matrizes entorpecidas. Usar uma lista (ou array inteiro) como índice é uma "indexação extravagante". Pode ser muito útil, mas copia os dados.

Por exemplo: y = x[[0, 1, 2], :]devolve uma cópia, enquantoy = x[:3,:] devolve uma vista.

Mesmo a indexação realmente maluca como x[4:100:5, :-10:-1, None]é a indexação "normal" e retornará uma visualização, portanto, não tenha medo de usar todos os tipos de truques de fatiamento em matrizes grandes.

x.astype(<dtype>) retornará uma cópia dos dados como o novo tipo, enquantox.view(<dtype>) retornará uma visualização.

Tenha cuidado com isso, entretanto ... É extremamente poderoso e útil, mas você precisa entender como os dados subjacentes são armazenados na memória. Se você tiver um array de floats e vê-los como ints, (ou vice-versa), numpy interpretará os bits subjacentes do array como ints.

Por exemplo, isso significa que, 1.0como um float de 64 bits em um sistema little-endian, será 4607182418800017408quando visto como um int de 64 bits e uma matriz de [ 0, 0, 0, 0, 0, 0, 240, 63]se for visto como um uint8. Isso é muito bom quando você precisa fazer algum tipo de alteração de bits em grandes arrays ... Você tem controle de baixo nível sobre como o buffer de memória é interpretado.

Joe Kington
fonte
Obrigado pelas dicas muito boas! Eu estava lendo o guia do usuário do Numpy e não entendi por que foi x[np.array([1, 1, 3, 1])] += 1modificado x. Agora entendi!
tnq177
boas dicas! Eu tenho outra pergunta. Como provar que numpy não dispara uma cópia e sim apenas uma visualização? o id de python () parece incapaz disso.
wuhaochi
3
@wuhaochi Se bé uma visão de a, então b.base is aserá True. Uma cópia (de qualquer matriz) sempre teráarr_copy.base is None
Jürg Merlin Spaak