Eu tenho uma numpy
matriz 2D . Existe uma maneira de criar uma exibição nele que inclua as primeiras k
linhas 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).
Respostas:
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 y
serão refletidas em x
e 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 += 10
irá modificar o array no local, enquanto x = x + 10
fará 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.0
fará o x
up-cast automaticamente para uma matriz de ponto flutuante, se ainda não foi. No entanto, x += 10.0
onde x
é uma matriz de inteiros, fará com que o 10.0
seja convertido para um int com a mesma precisão da matriz.
Além disso, muitas funções numpy usam um out
parâmetro, portanto, você pode fazer coisas como np.abs(x, x)
obter o valor absoluto de x
no 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.0
como um float de 64 bits em um sistema little-endian, será 4607182418800017408
quando 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.
b
é uma visão de a
, então b.base is a
será True
. Uma cópia (de qualquer matriz) sempre teráarr_copy.base is None
x[np.array([1, 1, 3, 1])] += 1
modificadox
. Agora entendi!