Numpy Tutorial - NumPy Array Reshape and Resize

  1. numpy.reshape()
  2. ndarray.reshape()
  3. reshape() Função/Método de Memória Compartilhada
  4. numpy.resize()

NumPy tem duas funções (e também métodos) para mudar as formas de array - reshape e resize. Eles têm uma diferença significativa que será o nosso foco neste capítulo.

numpy.reshape()

Vamos começar com a função para mudar a forma do array - reshape().

import numpy as np

arrayA = np.arange(8)
# arrayA = array([0, 1, 2, 3, 4, 5, 6, 7])

np.reshape(arrayA, (2, 4))
#array([[0, 1, 2, 3],
#       [4, 5, 6, 7]])

Ela converte um vetor de 8 elementos para o array da forma de (4, 2). Ele pode ser executado com sucesso porque a quantidade de elementos antes e depois da remodelação é idêntica. Ele eleva o ValueError se a quantidade for diferente.

In [1]: np.reshape(arrayA, (3, 4))
    ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
ValueError: cannot reshape array of size 8 into shape (3,4)

Vamos dar uma olhada de perto no array remodelado. A primeira linha é os 4 primeiros dados de arrayA e a segunda linha leva os 4 últimos. Ela preenche os dados na ordem da linha nesta conversão reformulada.

Você precisa alterar o parâmetro order se você quiser que a ordem de preenchimento dos dados seja coluna.

In [1]: np.reshape(arrayA, (2, 4), order='F')
Out[1]: array([[0, 2, 4, 6],
        	  [1, 3, 5, 7]])

O padrão de order é C que significa ler ou escrever os dados na ordem de índice em C, ou em palavras simples, na ordem da linha. F significa ler ou escrever dados em ordem de índice parecida com Fortan, ou digamos, na ordem de column. Você poderia consultar documentação oficial NumPy para saber mais detalhes sobre os diferentes métodos de indexação.

ndarray.reshape()

Além da função reshape, NumPy também tem o método reshape no objeto ndarray. O método tem os mesmos parâmetros que a função, mas sem o array dado como parâmetro.

In [1]: arrayB = arrayA.reshape((2, 4))
    
In [2]: arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [1]: arrayA
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7])    

Você pode ver que o método reshape é similar à função reshape. E você também deve estar ciente que o método ndarray.reshape() não altera os dados e a forma do array original, mas retorna uma nova instância ndarray.

reshape() Função/Método de Memória Compartilhada

O array convertido em função de reshape ou método compartilha a mesma memória do array original. Você pode pensar que é uma ‘cópia rasa’ em Python, onde se você alterar os dados em um array, os dados correspondentes no outro array também são modificados.

In [1]: arrayA = np.arange(8)
    	arrayB = arrayA.reshape((2, 4))
        arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [2]: arrayA[0] = 10
    	arrayA
Out[2]: array([10, 1, 2, 3, 4, 5, 6, 7]) 
In [3]: arrayB    
Out[3]:	array([[10, 1, 2, 3],
       		[4, 5, 6, 7]])    

numpy.resize()

O numpy.resize() é um pouco semelhante ao reshape no sentido da conversão de formas. Mas tem algumas diferenças significativas.

  1. Ele não tem o parâmetro order. A ordem de resize é a mesma de order='C' in reshape.
  2. Se o número de elementos do array alvo não for o mesmo que o array original, ele forçará a redimensionar, mas não levantará erros.

Vamos focar na segunda diferença.

In [1]: arrayA = np.arange(8)
        arrayB = np.resize(arrayA, (2, 4))
Out[1]: array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

O resultado é o mesmo que em reshpae se os números dos elementos forem os mesmos.

In [1]: arrayC = np.resize(arrayA, (3, 4))
    	arrayC
Out[1]: array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 1, 2, 3]])
In [2]: arrayD = np.resize(arrayA, (4, 4))
    	arrayD
Out[2]: array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 1, 2, 3],
       [4, 5, 6, 7]])

Se o novo array tiver mais linhas, ele irá repetir os dados no array original, mas não irá aumentar o erro.

In [1]: arrayE = np.resize(arrayA, (2, 2))
		arrayE
Out[1]: array([[0, 1],
       [2, 3]])    
In [2]: np.resize(arrayA, (1,4))
Out[2]: array([[0, 1, 2, 3]])

Se o número de elementos no novo array for menor, ele vai buscar o número de elementos necessários para preencher o novo array na ordem de linha.

Redimensionar’ Memória de Função/Método

O novo array não compartilha a mesma memória com o array original em função/método de resize. A mudança de dados em um array não é mapeada para o outro.

In [1]: arrayA = np.arange(8)
    	arrayB = arrayA.reshape((2, 4))
        arrayB
Out[2]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])
In [2]: arrayA[0] = 10
    	arrayA
Out[2]: array([10, 1, 2, 3, 4, 5, 6, 7]) 
In [3]: arrayB    
Out[3]:	array([[0, 1, 2, 3],
       		[4, 5, 6, 7]])