Mais tipos de dados

Tipos “maiores” ganham em operações de tipos misturados:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

np.array([1, 2, 3]) + 1.5

[/pastacode]

Atribuição nunca muda o tipo:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

a = np.array([1, 2, 3])
a.dtype
a[0] = 1.9     # <-- float é truncado para inteiro
a

[/pastacode]

Conversões forçadas:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

a = np.array([1.7, 1.2, 1.6])
b = a.astype(int)  # <-- truncagem para inteiro
b

[/pastacode]

Arredondamento:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

a = np.array([1.2, 1.5, 1.6, 2.5, 3.5, 4.5])
b = np.around(a)
b                    # ainda ponto flutuante
c = np.around(a).astype(int)
c

[/pastacode]

Tamanhos de tipos de dados diferentes

Inteiros (com sinal):

int8 8 bits
int16 16 bits
int32 32 bits (mesmo que int em uma plataforma 32 bits
int64 64 bits (mesmo que int em uma plataforma 64 bits

 

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

np.array([1], dtype=int).dtype
np.iinfo(np.int32).max, 2**31 - 1
np.iinfo(np.int64).max, 2**63 - 1

[/pastacode]

Inteiros sem sinal:

uint8 8 bits
uint16 16 bits
uint32 32 bits
uint64 64 bits

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

np.iinfo(np.uint32).max, 2**32 - 1
np.iinfo(np.uint64).max, 2**64 - 1

[/pastacode]

Pontos flutuante:

float16 16 bits
float32 32 bits
float64 64 bits (mesmo que float)
float96 96 bits, independente da plataforma (mesmo que np.longdouble)
float128 128 bits, independente da plataforma (mesmo que np.longdouble)

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

np.finfo(np.float32).eps
np.finfo(np.float64).eps
np.float32(1e-8) + np.float32(1) == 1
np.float64(1e-8) + np.float64(1) == 1

[/pastacode]

Tipos de dados pequenos

Se você não sabe se você precisa de tipos de dados espaciais é porque você provavelmente não precisa.

Comparação utilizando float32 ao invés de float64:

  • Metade do tamanho na memória e no disco;
  • Metade da largura de banda da memória requerida (pode ser mais rápido em algumas operações):

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

import time
a = np.zeros((1e6,), dtype=np.float64)
b = np.zeros((1e6,), dtype=np.float32)

tempo = time.time()
a*a
print time.time() - tempo
tempo = time.time()
b*b
print time.time() - tempo

[/pastacode]

  • Mas: grandes erros de arredondamento, as vezes, em lugares surpreendentes.

Tipos de dados estruturados

sensor_code string de 4 caracteres
position float
value float

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

amostra = np.zeros((6,), dtype=[('sensor_code', 'S4'),
                                ('position', float), ('value', float)])
print amostra.ndim
print amostra.shape
print amostra.dtype.names
amostra[:] = [('ALFA',   1, 0.37), ('BETA', 1, 0.11), ('TAU', 1,   0.13),
              ('ALFA', 1.5, 0.37), ('ALFA', 3, 0.11), ('TAU', 1.2, 0.13)]
print amostra

[/pastacode]

Acesso aos campos funciona pela indexação com nomes do campo:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

amostra['sensor_code']
amostra['value']
amostra[0]
amostra[0]['sensor_code'] = 'TAU'
amostra[0]

[/pastacode]

Múltiplos campos ao mesmo tempo:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

samples[['position', 'value']]

[/pastacode]

A indexação sofisticada funciona, como usual:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

samples[samples['sensor_code'] == 'ALFA']

[/pastacode]

Observação: existem um monte de outras sintaxes para a construção de arrays estruturadas, veja aqui e aqui.

maskedarray: lidando com (propagação de) dados perdidos

Para pontos flutuantes pode-se usar os NaN, mas máscaras funcionam para todos os tipos:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
x
y = np.ma.array([1, 2, 3, 4], mask=[0, 1, 1, 1])
x + y

[/pastacode]

Mascarando versões de funções comuns:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

np.ma.sqrt([1, -1, 2, -2])

[/pastacode]

Observação: Existe outro array siblings útil.