- Aprender
- Computação e TI
- Ciência de dados e IA
- Análise de dados com Python
- Arrays NumPy e computação vetorizada
Arrays NumPy e computação vetorizada
IntermediárioAula 1 de 8 do curso Curso de Análise de dados com Python
O que você vai aprender
- Construir arrays NumPy a partir de dados Python e com as funções de criação do NumPy, descrever um array por sua forma e seu tipo de dados, e escolher e converter tipos de dados sem perder informações por acidente.
- Explicar o que é um array do NumPy e como ele difere de uma listaDescrever um array por suas dimensões, forma, número de elementos e tipo de dados, e explicar por que arrays se comportam e apresentam desempenho diferente das listas do Python.
- Criar arrays a partir de listas e com as funções de criação do NumPyTransformar listas em arrays e gerar arrays preenchidos, sequências numéricas e grades com espaçamento uniforme, com a forma e o tipo necessários.
- Escolher, inspecionar e converter tipos de dadosLer e definir o tipo de dados de um array, prever o tipo escolhido pelo NumPy e converter entre tipos evitando truncamento, estouro e perda de valores ausentes.
- Explicar o que é um array do NumPy e como ele difere de uma lista
- Selecionar valores individuais, linhas, colunas e blocos; selecionar por listas de posições ou por condições; e saber quando uma seleção compartilha seus dados com o array original.
- Indexar e fatiar arrays unidimensionais e bidimensionaisUsar posições e fatias, uma por eixo, para ler e alterar elementos, linhas, colunas e blocos.
- Selecionar por listas de posições e distinguir visões de cópiasSelecionar quaisquer elementos, linhas ou colunas com arrays de inteiros e prever se um resultado compartilha memória com o array original.
- Filtrar por condições usando máscaras booleanas e np.whereConstruir máscaras de verdadeiro ou falso a partir de comparações, combiná-las e usá-las para filtrar, contar, substituir e escolher valores.
- Indexar e fatiar arrays unidimensionais e bidimensionais
- Reorganizar os mesmos valores em uma nova forma, trocar linhas e colunas, adicionar ou remover eixos de comprimento 1 e unir ou dividir arrays ao longo de um eixo.
- Alterar a forma de um array e permutar seus eixosRemodelar, achatar e transpor arrays e adicionar ou remover eixos de comprimento 1, prevendo a ordem dos valores.
- Unir e dividir arraysCombinar arrays ao longo de um eixo existente ou novo e dividir um array em partes, verificando se as formas são compatíveis.
- Alterar a forma de um array e permutar seus eixos
- Escrever cálculos sobre arrays inteiros em vez de laços elemento a elemento, aplicar as funções universais do NumPy e combinar arrays de formas diferentes com as regras de difusão.
- Calcular elemento a elemento em vez de usar laçosUsar operadores aritméticos e de comparação em arrays inteiros e saber como eles tratam formas, divisão por zero e atualizações no próprio objeto.
- Aplicar funções universais a arrays inteirosUsar as funções matemáticas elemento a elemento do NumPy, incluindo arredondamento e funções de dois arrays, e tratar valores fora do domínio de uma função.
- Combinar arrays de formas diferentes por difusãoAplicar as regras de difusão para prever se duas formas podem ser combinadas e qual será a forma resultante, e corrigir erros de forma adicionando um eixo.
- Calcular elemento a elemento em vez de usar laços
- Reduzir arrays a totais, médias, extremos, medidas de dispersão, medianas e contagens, para o array inteiro ou ao longo de um eixo escolhido, e tratar corretamente valores ausentes e subconjuntos.
- Agregar um array inteiro ou ao longo de um eixoCalcular somas, médias, extremos, posições, totais acumulados e medidas de dispersão para o array inteiro ou por linha ou coluna, e prever a forma do resultado.
- Usar medianas, percentis, ordenação e valores distintosDescrever a tendência central e a dispersão dos dados com estatísticas baseadas na ordem, ordenar valores e arrays relacionados e contar valores distintos.
- Resumir dados com valores ausentes e condiçõesIdentificar, contar, remover e preencher valores ausentes, usar agregações que ignoram NaN e resumir apenas os valores que atendem a uma condição ou pertencem a um grupo.
- Agregar um array inteiro ou ao longo de um eixo
- Criar um gerador de números aleatórios com semente definida, obter amostras reproduzíveis de distribuições comuns, embaralhar e amostrar dados e estimar resultados com simulações vetorizadas.
- Obter amostras aleatórias reproduzíveis com um objeto GeneratorCriar um objeto Generator com uma semente, obter inteiros, decimais, valores de uma distribuição normal e amostras de uma lista, embaralhar dados e manter os resultados reproduzíveis.
- Executar simulações vetorizadasEstimar probabilidades e comportamento de longo prazo obtendo todos os valores aleatórios de uma vez e resumindo-os com operações em arrays.
- Obter amostras aleatórias reproduzíveis com um objeto Generator
Guia de estudo de Arrays NumPy e computação vetorizada
1Criar arrays e controlar seus tipos de dados
Dados numéricos ficam mais fáceis de usar quando sua estrutura e seu tipo de armazenamento estão claros. Construa arrays a partir de valores existentes ou de uma forma planejada e depois leia suas dimensões, seu número de elementos e seu tipo de dados. Escolha funções de criação adequadas à sua entrada e veja como conversão, arredondamento, estouro e valores ausentes afetam o que o array realmente armazena. Essas escolhas determinam se cálculos posteriores preservam as informações de que você precisa.
1.1 Explicar o que é um array do NumPy e como ele difere de uma lista
O NumPy armazena dados numéricos em arrays para que uma expressão possa operar sobre muitos valores. Importe-o com import numpy as np; o nome curto np é a forma usual de chamar suas funções.
Leia a estrutura de um array
Um ndarray é uma grade retangular cujos elementos compartilham um tipo de dados. Uma dimensão também é chamada de eixo. Comece com uma tabela pequena:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
Seus atributos respondem a quatro perguntas diferentes:
| Atributo | Significado | Valor para a |
|---|---|---|
ndim | Número de eixos | 2 |
shape | Comprimento de cada eixo | (2, 3) |
size | Total de elementos | 6 |
dtype | Tipo de cada elemento | Geralmente int64 em um computador de 64 bits |
O eixo 0 indexa linhas; o eixo 1 indexa colunas. Uma tabela de dados com uma linha por pessoa e colunas para altura, massa e idade teria forma (100, 3) para 100 pessoas. O produto dos valores da forma fornece o número de elementos.
Um vetor não tem eixo de linha ou de coluna
np.array([2, 4, 6, 8]) tem forma (4,) e um eixo. A vírgula faz dela uma tupla de uma entrada. A forma (1, 4) tem dois eixos: uma linha e quatro colunas. A forma (4, 1) também tem dois eixos, mas quatro linhas e uma coluna. Esses arrays contêm quatro valores, mas se comportam de modo diferente quando combinados com outros arrays. np.array(7) é um array de dimensão zero: sua forma é () e seu ndim é 0.
Arrays mudam o significado dos operadores
Uma lista é um contêiner de uso geral do Python. Um array é projetado para cálculos em posições correspondentes.
| Expressão | Resultado |
|---|---|
[1, 2, 3] * 2 | [1, 2, 3, 1, 2, 3] |
np.array([1, 2, 3]) * 2 | array([2, 4, 6]) |
[1, 2] + [3, 4] | [1, 2, 3, 4] |
np.array([1, 2]) + np.array([3, 4]) | array([4, 6]) |
Na adição de arrays, 1 forma um par com 3 e 2 forma um par com 4. O array mantém o mesmo tamanho.
Por que arrays numéricos são eficientes
Um array numérico recém-criado armazena valores do mesmo tipo juntos na memória. O NumPy executa o laço sobre esses valores em código compilado, evitando uma operação separada em Python para cada número. Um milhão de valores float64 ocupa 8.000.000 de bytes de armazenamento dos elementos, disponíveis como a.nbytes em um array desse tamanho. Uma lista Python também armazena referências a objetos Python, então precisa de muito mais espaço. Os ganhos de desempenho dependem do cálculo e do computador.
O tamanho de um array não aumenta por meio de um método append no próprio objeto. np.append(a, value) aloca um novo array. Para dados coletados um valor por vez, construa uma lista Python e converta uma vez. A entrada aninhada deve ser retangular: np.array([[1, 2], [3]]) gera ValueError porque os comprimentos de suas linhas diferem.
Reconheça os resultados exibidos
print(np.array([1, 2, 3])) mostra [1 2 3]. Uma exibição interativa usa array([1, 2, 3]). Para np.array([5, 6])[0] em um computador de 64 bits, o NumPy 2 exibe np.int64(5); ele participa de operações aritméticas como o número 5.
Principais conclusões
- A forma fornece o comprimento de cada eixo; o número de elementos conta todos os elementos.
- Uma forma de 1 dimensão, como
(4,), difere de uma linha ou coluna de 2 dimensões. - A aritmética de arrays atua sobre valores em posições correspondentes.
- Arrays numéricos armazenam um único tipo de dados e permitem cálculos eficientes em código compilado.
- A entrada aninhada deve ter linhas de mesmo comprimento.
1.2 Criar arrays a partir de listas e com as funções de criação do NumPy
Escolha uma função de criação perguntando o que você conhece: os valores propriamente ditos, uma forma e um valor de preenchimento, um passo ou uma quantidade necessária de pontos. Essa escolha faz o código expressar como os dados devem ser construídos.
Comece pelos valores ou por uma forma
np.array([3, 1, 4]) cria um vetor. Uma lista de listas de mesmo comprimento cria uma tabela. Passe os valores como uma única sequência; np.array(1, 2, 3) não fornece três elementos corretamente.
| Função | Exemplo | O que cria |
|---|---|---|
np.zeros | np.zeros((3, 4)) | Três linhas de quatro zeros |
np.ones | np.ones((2, 3)) | Duas linhas de três uns |
np.full | np.full((2, 2), 7) | Um array de 2 por 2 preenchido com 7 |
np.empty | np.empty((3, 4)) | Armazenamento reservado, não inicializado |
Para uma forma multidimensional, os parênteses importam. np.zeros((2, 3)) passa uma tupla. Em np.zeros(2, 3), o Python envia 3 como argumento do tipo de dados, o que causa um erro de tipo. Zeros e uns usam float64 por padrão; full infere seu tipo de dados a partir do valor de preenchimento. Adicione dtype=int quando precisar armazenar números inteiros.
empty não garante zeros nem valores iniciais significativos. Leia seus valores somente depois de atribuir cada elemento que você usará. zeros é uma escolha mais simples quando um zero inicial tem significado.
Escolha um passo ou uma quantidade de pontos
np.arange(start, stop, step) segue a ideia de passos de range do Python. np.arange(2, 11, 3) resulta em [2 5 8]: comece em 2 e some 3 enquanto permanecer abaixo de 11. Com um argumento, np.arange(5) começa em 0 e resulta em [0 1 2 3 4].
Passos de ponto flutuante podem produzir extremos inesperados. Por exemplo, np.arange(1, 1.3, 0.1) inclui o valor exibido 1,3 porque o arredondamento binário afeta o cálculo da sequência. Para uma grade decimal com quantidade fixa de pontos, use linspace:
grid = np.linspace(0, 1, 5)
# array([0. , 0.25, 0.5 , 0.75, 1. ])
Ambos os extremos são incluídos por padrão. Cinco pontos formam quatro intervalos. Dez pontos entre 0 e 1 formam nove intervalos, então seu espaçamento é aproximadamente 0,111; passos de 0,1 exigem 11 pontos.
Reutilize uma estrutura existente
np.zeros_like(a), np.ones_like(a) e np.full_like(a, value) criam novos arrays com a forma e o tipo de dados de a. O tipo de dados herdado importa: preencher um modelo de inteiros com um decimal pode causar a perda da parte decimal, a menos que você solicite um tipo de ponto flutuante. np.eye(3) cria uma matriz identidade quadrada com uns na diagonal e zeros nas demais posições.
Aloque uma tabela de dados uma vez
Para a precipitação em milímetros em três estações ao longo de quatro semanas:
rain = np.zeros((3, 4))
rain[0] = [12.0, 0.0, 5.5, 8.0]
A primeira atribuição preenche uma linha e preserva a forma (3, 4). Se o número de leituras for conhecido, reservar a tabela inteira evita alocar repetidamente arrays maiores. Se a quantidade de entradas for desconhecida, acumule os valores em uma lista e chame np.array quando a coleta terminar.
Principais conclusões
- Passe uma forma multidimensional como uma tupla.
arangeespecifica um passo;linspaceespecifica uma quantidade de pontos.linspaceinclui os dois extremos por padrão.emptydeve ser preenchido antes que seus valores sejam usados.- As funções like herdam tanto a forma quanto o tipo de dados.
- Aloque uma forma final conhecida uma vez.
1.3 Escolher, inspecionar e converter tipos de dados
O tipo de dados de um array controla o que ele pode armazenar e quanta memória cada valor precisa. Escolher o tipo adequado também evita que cálculos percam informações sem aviso.
Inspecione o tipo de armazenamento
int64 armazena números inteiros de 64 bits, float64 armazena números binários de ponto flutuante e bool armazena valores verdadeiro ou falso. Tipos Unicode como <U5 armazenam texto com um comprimento máximo de caracteres. a.itemsize é o número de bytes por elemento; a.nbytes é a.size * a.itemsize. Um float64 usa 8 bytes e tem precisão de cerca de 15 algarismos decimais significativos.
Em computadores típicos de 64 bits, entradas de números inteiros usam inteiros de 64 bits. O NumPy 2 também usa esse padrão no Windows de 64 bits. Entradas decimais normalmente resultam em float64.
A inferência escolhe um tipo compartilhado
np.array([1, 2.5]) se torna [1. 2.5]: o inteiro é representado como um número de ponto flutuante. np.array([True, 2]) se torna [1 2]. Misturar números e texto pode transformar o array inteiro em texto, então um rótulo como 'n/a' pode fazer operações aritméticas posteriores falharem. Inspecione dtype quando dados aparentemente numéricos não puderem ser somados ou multiplicados.
Converta de forma consciente
astype retorna uma cópia convertida:
x = np.array([1.7, -1.7, 2.5])
whole = x.astype(int)
# array([ 1, -1, 2])
Essa conversão corta em direção a zero; ela não arredonda. np.round(x).astype(int) resulta em [2 -2 2] porque valores exatamente na metade são arredondados para o valor par mais próximo. Texto como '1.5' é convertido com astype(float), mas 'n/a' gera ValueError. Limpe os marcadores antes da conversão.
Atribuições usam o tipo de dados do destino. Após a = np.array([1, 2, 3]), atribuir a[0] = 9.9 armazena 9 sem aviso. Converter o array inteiro para ponto flutuante antes permite que atribuições posteriores preservem decimais.
Inteiros de tamanho fixo podem sofrer estouro
Um int8 armazena valores de −128 a 127; um uint8 armazena de 0 a 255. Somar dois arrays uint8 que contêm 250 e 10 produz 4 devido ao retorno ao outro extremo da faixa. Multiplicar um array int8 que contém 100 por 2 produz −56. Um inteiro Python que não cabe no tipo do array, como 300 somado a um array int8 no NumPy 2, gera OverflowError. Amplie os tipos inteiros pequenos antes de cálculos que possam exceder sua faixa.
Divisão e decimais aproximados
| Operação | Exemplo | Resultado |
|---|---|---|
| Divisão verdadeira | np.array([7, 8]) / 2 | [3.5 4.] |
| Divisão com piso | np.array([7, -7]) // 2 | [3 -4] |
| Resto | np.array([7, -7]) % 2 | [1 1] |
A divisão com piso arredonda para baixo, em direção ao infinito negativo, o que difere do truncamento para resultados negativos. A divisão verdadeira retorna resultados de ponto flutuante para entradas inteiras.
Muitas frações decimais são aproximações em binário. 0.1 + 0.2 == 0.3 é falso; np.isclose compara valores correspondentes com uma tolerância, e np.allclose fornece uma resposta para o array inteiro.
O marcador de valor ausente np.nan é de ponto flutuante. Arrays de inteiros não podem armazená-lo. Portanto, np.array([1, 2, np.nan]) se torna de ponto flutuante; converter valores ausentes para inteiros não os corrige e pode produzir resultados sem significado.
Principais conclusões
- Um tipo de dados rege todos os elementos, incluindo valores atribuídos posteriormente.
astype(int)trunca em direção a zero; o arredondamento é uma etapa separada.- Inteiros pequenos de tamanho fixo podem sofrer estouro durante operações aritméticas.
- Use comparações baseadas em tolerância para decimais aproximados.
- NaN precisa de um tipo de dados de ponto flutuante.
2Selecionar e filtrar dados em arrays
Uma análise raramente precisa de todos os valores exatamente em sua ordem original. Selecione posições individuais, fatias regulares, registros arbitrários ou entradas que satisfaçam uma condição. Verifique se um resultado compartilha memória com sua origem antes de editá-lo. As máscaras booleanas permitem que a mesma regra de seleção seja usada para filtragem, substituição, contagens e proporções, preservando registros completos quando sua pergunta exigir isso.
2.1 Indexar e fatiar arrays unidimensionais e bidimensionais
A indexação localiza valores por posição. O fatiamento seleciona uma sequência regular de posições. Em uma tabela, escreva um seletor para cada eixo, para que o código indique tanto as linhas quanto as colunas necessárias.
Leia um vetor
Para a = np.array([10, 20, 30, 40, 50]), a posição 0 contém 10 e a posição −1 contém 50. Uma fatia tem a forma start:stop:step, com o valor final excluído:
| Seleção | Resultado |
|---|---|
a[1:4] | [20 30 40] |
a[::2] | [10 30 50] |
a[::-1] | [50 40 30 20 10] |
a[3:10] | [40 50] |
Omitir o início ou o fim estende a seleção até o extremo correspondente. Uma fatia pode ultrapassar o array e ser encurtada automaticamente. Uma única posição inválida, como a[5], gera IndexError.
Dê a cada eixo da tabela seu próprio seletor
m = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
m[1, 2] lê a linha 1, coluna 2, fornecendo 6. A vírgula separa os eixos. Dois-pontos sozinhos selecionam o eixo inteiro: m[0, :] fornece a primeira linha [1 2 3], e m[:, 1] fornece a segunda coluna [2 5 8]. Para um bloco, m[:2, 1:] seleciona as linhas 0 e 1 e as colunas 1 e 2, fornecendo [[2 3] [5 6]].
Evite tratar a indexação com colchetes repetidos como intercambiável com a indexação por vírgula. m[1][2] localiza o mesmo escalar que m[1, 2]. Mas m[:][0] primeiro seleciona todas as linhas e depois seleciona a primeira linha. Ele não seleciona a primeira coluna, que é m[:, 0].
Preveja quais eixos permanecem
Um único seletor inteiro remove seu eixo. Uma fatia mantém seu eixo mesmo quando apenas uma posição é selecionada. Assim, m[:, 1] tem forma (3,), enquanto m[:, 1:2] tem forma (3, 1). Ambos selecionam 2, 5 e 8, mas apenas o segundo mantém um eixo de coluna. Essa diferença se torna importante ao subtrair ou multiplicar arrays com outras formas.
A mesma regra se estende além das tabelas. Se t.shape é (2, 3, 4), t[0] tem forma (3, 4), t[0, 1] tem forma (4,), e t[:, :, 0] tem forma (2, 3). Quaisquer eixos finais omitidos do índice são selecionados por inteiro.
Altere as posições selecionadas
A atribuição por meio de um índice escreve no array existente. a[1:3] = 0 substitui ambos os valores selecionados por zero; o escalar é aplicado em toda a seleção. m[0] = [0, 0, 0] substitui uma linha completa. Os valores atribuídos devem ser compatíveis com a forma da seleção e são convertidos para seu tipo de dados.
Para quatro estudantes e três provas:
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
scores[2] é o [88 91 95] do terceiro estudante. scores[:, -1] fornece os resultados da última prova [92 58 95 80]. scores[1:3, :2] fornece [[64 70] [88 91]]: dois estudantes, cada um mantendo duas colunas de provas.
Principais conclusões
- Os índices começam em 0; índices negativos contam a partir do fim.
- Fatias excluem o fim e podem ser encurtadas no limite de um array.
- Use seletores separados por vírgula para eixos distintos.
- Um inteiro remove um eixo; uma fatia o mantém.
- A atribuição por meio de um índice altera os valores selecionados.
2.2 Selecionar por listas de posições e distinguir visões de cópias
Uma seleção pode compartilhar seus dados com o array original ou ter dados independentes. Saber qual é o caso evita que alterações em uma pequena seleção modifiquem inesperadamente uma tabela maior.
Distinga referências ao mesmo objeto, uma visão e uma cópia
| Código | Relação | Efeito de alterar b |
|---|---|---|
b = a | Dois nomes para um objeto | Altera a |
b = a[2:5] | Uma visão de fatia que compartilha dados | Altera a parte correspondente de a |
b = a[2:5].copy() | Dados independentes | Deixa a inalterado |
Para a = np.arange(6) e b = a[2:5], atribuir b[0] = 99 faz a ser igual a [0 1 99 3 4 5]. A primeira posição da visão se refere à posição 2 no original. Isso difere do fatiamento de uma lista Python, que cria uma nova lista.
Copie antes de editar quando o original precisar permanecer intacto. Uma pequena visão mantida também pode manter uma grande área de memória dos dados originais ativa; copiar essa pequena parte permite que ela exista de forma independente.
Selecione posições arbitrárias
A indexação avançada por inteiros usa uma lista ou array de inteiros. Ela permite posições reordenadas e repetidas:
a = np.array([10, 20, 30, 40, 50])
a[[4, 0, 0]]
# array([50, 10, 10])
Para m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), m[[0, 2]] seleciona a primeira e a terceira linhas. m[:, [2, 0]] seleciona a última e a primeira colunas nessa ordem, resultando em [[3 1] [6 4] [9 7]].
Duas listas de inteiros em um índice selecionam coordenadas pareadas. m[[0, 2], [1, 2]] pareia a linha 0 com a coluna 1 e a linha 2 com a coluna 2, produzindo [2 9]. Ela não seleciona todas as combinações. Para obter o bloco formado por ambas as linhas e ambas as colunas, use:
m[np.ix_([0, 2], [1, 2])]
# array([[2, 3], [8, 9]])
Selecionar primeiro as linhas e depois as colunas, m[[0, 2]][:, [1, 2]], fornece o mesmo bloco.
Leitura e atribuição se comportam de modo diferente
A indexação avançada por inteiros e a filtragem booleana retornam cópias. Se c = a[[0, 1]], alterar c[0] deixa a inalterado. Mas a[[0, 1]] = -1 escreve diretamente nessas posições originais. Uma seleção salva e uma atribuição por meio de um índice são operações diferentes.
Isso também explica por que edições encadeadas podem não atingir a origem. Em a[[0, 1]][0] = -1, a primeira seleção já é uma cópia temporária. A escrita final altera esse array temporário, não a.
Verifique o compartilhamento diretamente
np.shares_memory(x, y) verifica se dois arrays ocupam uma área comum na memória. Retorna verdadeiro para uma fatia comum não vazia e falso para uma cópia obtida por indexação avançada por inteiros. O atributo base pode identificar o objeto que detém a memória, mas não precisa identificar o array que você fatiou mais recentemente. Se a = np.arange(6), b = a[2:5] e c = b[0:2], então c.base is a é verdadeiro e c.base is b é falso. Use shares_memory quando a questão for especificamente se dois arrays compartilham dados.
Principais conclusões
- A atribuição cria outra referência ao array; uma fatia básica compartilha seus dados.
- Use
.copy()para uma seleção independente. - A indexação avançada por inteiros preserva a ordem solicitada e permite repetições.
- Duas listas de índices inteiros pareiam coordenadas;
np.ix_seleciona todas as combinações. - Leituras por indexação avançada por inteiros copiam, mas atribuições diretas por índice atualizam a origem.
- Use
np.shares_memorypara testar o compartilhamento entre arrays.
2.3 Filtrar por condições usando máscaras booleanas e np.where
Uma máscara booleana registra quais valores satisfazem uma condição. Depois que uma máscara existe, as mesmas decisões de verdadeiro ou falso podem selecionar valores, contar eventos ou escolher substituições.
Construa e aplique uma máscara
t = np.array([18.5, 22.0, 15.2, 25.8, 21.1])
warm = t > 20
t[warm]
# array([22. , 25.8, 21.1])
A comparação produz [False True False True True]. A indexação booleana mantém as posições verdadeiras e retorna uma cópia. Uma máscara de 1 dimensão usada em um eixo deve ter o mesmo comprimento desse eixo.
Para combinar condições, use & para e, | para ou e ~ para não. Coloque cada comparação entre parênteses:
comfortable = (t > 18) & (t < 23)
t[comfortable]
# array([18.5, 22. , 21.1])
and e or do Python tentam obter um único valor lógico de um array inteiro e falham para arrays com vários elementos. Omitir os parênteses também altera a forma como o Python agrupa a expressão, pois operadores bit a bit têm precedência sobre comparações.
Conte, meça ou teste condições
True contribui com 1 e False contribui com 0. warm.sum() é 3 e warm.mean() é 0,6, a fração de dias acima de 20 °C. np.count_nonzero(warm) também conta as entradas verdadeiras. warm.any() pergunta se pelo menos um dia é quente; warm.all() pergunta se todos os dias são quentes.
Essas operações respondem a perguntas diferentes de t[warm].mean(), que calcula a temperatura média nos dias quentes. A média de uma máscara mede uma proporção; a média das medições selecionadas mantém a unidade da medição.
Substitua valores ou escolha entre alternativas
A atribuição por meio de uma máscara atualiza as posições selecionadas. Com t2 = t.copy(), a linha t2[t2 < 16] = 16 eleva as leituras baixas para 16. np.clip(t, 16, 25) retorna um novo array limitado nos dois extremos, [18.5 22. 16. 25. 21.1].
np.where(condition, x, y) constrói um novo resultado que recebe x nas posições verdadeiras e y nas posições falsas. np.where(t > 20, 'warm', 'cool') fornece um rótulo em cada posição original. Já a filtragem encurta o resultado. Com apenas uma condição, np.where(t > 20) retorna uma tupla de arrays de índices, aqui (array([1, 3, 4]),).
Mantenha valores ou registros completos
Uma máscara de mesma forma em um array de 2 dimensões extrai os elementos correspondentes em um vetor achatado. Em m[m > 5], a estrutura das linhas é perdida. Para manter registros completos, derive um valor booleano por linha a partir de uma coluna:
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
scores[scores[:, 2] >= 90]
# array([[78, 85, 92], [88, 91, 95]])
Encontre valores ausentes explicitamente
NaN não é igual nem a si mesmo em comparações. Comparações de igualdade e ordem com NaN são falsas; a comparação de desigualdade é verdadeira. Assim, nem x == np.nan nem x != np.nan identifica corretamente as entradas presentes e ausentes. np.isnan(x) marca as posições ausentes, e x[~np.isnan(x)] mantém os valores presentes.
Principais conclusões
- Uma máscara contém uma decisão de verdadeiro ou falso por posição testada.
- Combine comparações entre parênteses com
&,|e~. - A soma de uma máscara conta correspondências; sua média fornece a proporção delas.
- Use uma máscara com o comprimento do eixo das linhas para filtrar registros completos.
np.whereescolhe valores em cada posição.- Use
np.isnanpara encontrar NaN.
3Remodelar, transpor e unir arrays
Uma forma útil de array expressa como os dados se relacionam: meses dentro de trimestres, medições dentro de registros ou lotes dentro de uma coleção maior. Reorganize valores com a remodelagem, troque os papéis dos eixos com a transposição e adicione eixos de comprimento um quando um vetor precisar assumir o papel de linha ou coluna. A união e a divisão combinam ou separam esses grupos, com verificações de forma que mantêm a estrutura desejada intacta.
3.1 Alterar a forma de um array e permutar seus eixos
Alterar a forma muda como os valores são agrupados em eixos. Remodelar, transpor e adicionar um eixo têm funções diferentes, mesmo quando algumas dessas operações produzem a mesma forma final.
Remodele sem alterar o número de elementos
a = np.arange(6)
r = a.reshape(2, 3)
# array([[0, 1, 2], [3, 4, 5]])
A ordem padrão preenche uma linha por vez: o último eixo varia mais rapidamente. Remodelar os mesmos valores para (3, 2) resulta em [[0 1] [2 3] [4 5]]. O produto das novas dimensões deve ser igual ao número original de elementos. Doze elementos cabem em (3, 4), mas não em (5, 3).
Uma dimensão pode ser -1, permitindo que o NumPy infira seu comprimento. np.arange(12).reshape(-1, 3) fornece quatro linhas de três elementos; reshape(2, -1) fornece duas linhas de seis elementos. Duas dimensões desconhecidas não são permitidas porque seus comprimentos individuais não podem ser determinados apenas pelo total.
A transposição troca os eixos
Para r acima, r.T é [[0 3] [1 4] [2 5]], com forma (3, 2). Cada coluna antiga agora é uma linha. Essa disposição difere de r.reshape(3, 2), embora as formas resultantes sejam iguais.
| Operação | O que acontece com r |
|---|---|
r.reshape(3, 2) | Lê os valores linha por linha e os reagrupa |
r.T | Troca os papéis de linhas e colunas |
Uma transposição é útil quando a próxima operação precisa da ordem inversa dos eixos. Uma remodelagem é útil quando uma sequência já tem um agrupamento significativo, como meses agrupados em trimestres.
A transposição de um array de 1 dimensão não cria uma coluna
v = np.arange(3) tem apenas um eixo, então v.T continua com forma (3,). Adicione um eixo explicitamente:
column = v[:, np.newaxis] # shape (3, 1)
row = v[np.newaxis, :] # shape (1, 3)
v.reshape(-1, 1) e np.expand_dims(v, 1) também criam uma coluna. np.squeeze(column) remove seu eixo de comprimento um e retorna a forma (3,). Adicionar um eixo não altera os valores, mas indica como eles devem ser alinhados em operações aritméticas posteriores.
Achatamento e compartilhamento de memória
r.ravel() e r.flatten() listam os valores em um resultado de 1 dimensão. ravel retorna uma visão quando possível; flatten sempre copia. reshape(-1) é outra forma de solicitar uma organização de 1 dimensão, mas o compartilhamento de memória depende da disposição da entrada. A remodelagem pode precisar de uma cópia; a transposição compartilha dados em sua visão do array. Use .copy() quando for necessário armazenamento independente.
Agrupe valores mensais em trimestres
Para monthly = np.array([120, 135, 150, 160, 155, 170, 180, 175, 165, 150, 140, 130]), monthly.reshape(4, 3) cria quatro linhas de trimestres, cada uma com três meses. Somar cada linha com .sum(axis=1) resulta em [405 485 520 420]. O primeiro total é 120 + 135 + 150 = 405. A remodelagem funciona porque a entrada em ordem cronológica já mantém juntos os meses de cada trimestre.
Principais conclusões
- A remodelagem preserva o número de elementos e segue a ordem por linhas por padrão.
- Uma dimensão
-1pode ser inferida. - A transposição troca os papéis dos eixos e pode diferir de uma remodelagem com a mesma forma.
- Use um novo eixo para transformar um vetor em linha ou coluna.
flattencopia;ravele a remodelagem podem compartilhar dados.
3.2 Unir e dividir arrays
A união combina valores de vários arrays. A divisão corta um array em partes. Primeiro decida se a operação deve estender um eixo existente ou introduzir um novo.
Concatene ao longo de um eixo existente
np.concatenate([a, b], axis=0) une vetores pelas extremidades. Unir [1 2] a [3 4 5] resulta em [1 2 3 4 5].
Para dois arrays, cada um com forma (2, 3), o eixo 0 adiciona linhas e resulta em (4, 3). O eixo 1 adiciona colunas e resulta em (2, 6). Apenas o eixo de união pode ter comprimentos diferentes. Assim, as formas (2, 3) e (2, 2) podem ser unidas ao longo do eixo 1 em (2, 5), mas não ao longo do eixo 0, pois seus números de colunas diferem.
Os arrays devem ser passados juntos como uma sequência, como [a, b]. A união cria um novo array combinado e copia os dados das entradas.
Empilhe ao longo de um novo eixo
Para p = np.array([1, 2, 3]) e q = np.array([4, 5, 6]):
| Expressão | Forma | Disposição |
|---|---|---|
np.concatenate([p, q]) | (6,) | Um vetor mais longo |
np.stack([p, q]) | (2, 3) | Um vetor por linha |
np.stack([p, q], axis=1) | (3, 2) | Um vetor por coluna |
stack exige formas de entrada iguais e adiciona um eixo. concatenate preserva o número de eixos. As funções auxiliares expressam disposições comuns: vstack([p, q]) cria linhas, hstack([p, q]) une essas entradas de 1 dimensão pelas extremidades, e column_stack([p, q]) cria colunas. O comportamento de hstack em 1 dimensão explica por que seu nome, por si só, não basta para prever uma tabela.
Divida por limites ou por quantidade de partes
np.split(np.arange(10), [3, 7]) corta antes das posições 3 e 7, produzindo [0 1 2], [3 4 5 6] e [7 8 9]. As posições de corte não são comprimentos das partes.
Um segundo argumento inteiro solicita partes iguais: np.split(x, 3) pede três partes iguais. Dez elementos não podem ser divididos igualmente em três partes de tamanho inteiro, então isso gera ValueError. np.array_split(np.arange(10), 3) permite comprimentos desiguais e produz 4, 3 e 3. Essas chamadas de divisão retornam uma coleção de arrays, não um único array com um novo eixo de empilhamento.
Construa uma tabela de medições
h = np.array([1.62, 1.75, 1.80]) # meters
w = np.array([55.0, 72.5, 80.0]) # kilograms
data = np.column_stack([h, w])
A forma (3, 2) representa três pessoas com altura e massa em colunas. Selecionar data[:, 1] / data[:, 0] ** 2 calcula a massa dividida pela altura ao quadrado para cada linha, resultando em aproximadamente 21,0; 23,7 e 24,7 kg/m². Manter os dois arrays de medições na mesma ordem de pessoas é essencial.
Se a entrada chegar em lotes, reúna os arrays dos lotes em uma lista Python e chame concatenate uma vez. Unir novamente um array crescente a cada passagem do laço copia repetidamente seus dados existentes.
Principais conclusões
- A concatenação estende um eixo; o empilhamento adiciona um.
- As dimensões que não são usadas na união devem coincidir para a concatenação.
- Use
column_stackpara transformar vetores correspondentes em colunas de uma tabela. - Posições de divisão são limites; uma quantidade inteira de partes solicita partes iguais.
array_splitpermite partes de comprimentos desiguais.- Reúna os lotes primeiro e una-os uma vez.
4Substituir laços por aritmética vetorizada, funções universais e difusão
Expressões sobre arrays inteiros permitem descrever operações numéricas sem escrever um laço Python para cada valor. Comece com aritmética em posições correspondentes, depois aplique as funções matemáticas do NumPy e combine formas diferentes por difusão. Analisar as formas explica quais valores são pareados e quais são repetidos. Regras de conversão de tipo, entradas inválidas e avisos de divisão também importam quando uma expressão curta executa muitos cálculos de uma vez.
4.1 Calcular elemento a elemento em vez de usar laços
A vetorização expressa um cálculo para arrays inteiros. O NumPy cuida do trabalho repetido em cada elemento em código compilado, para que a expressão Python permaneça próxima do cálculo desejado.
Transforme um laço em aritmética de posições correspondentes
prices = np.array([2.50, 4.00, 1.20])
qty = np.array([3, 1, 5])
line_totals = prices * qty
order_total = line_totals.sum()
Os produtos são [7.5 4. 6.] e sua soma é 17,5. Cada preço é pareado com sua própria quantidade. Um laço Python que atualiza um total produz o mesmo resultado, mas faz o Python tratar cada par separadamente.
Todos os operadores aritméticos atuam elemento a elemento: +, -, *, /, //, % e **. Um escalar é aplicado a cada entrada. 10 - np.array([1, 2, 3]) resulta em [9 8 7]; a ordem dos operandos continua importante. Dois arrays precisam ter formas iguais ou compatíveis com difusão.
Distinga produtos elemento a elemento de produtos matriciais
* multiplica entradas correspondentes. Para A = np.array([[1, 2], [3, 4]]) e B = np.array([[5, 6], [7, 8]]), A * B resulta em [[5 12] [21 32]]. A multiplicação de matrizes usa @ e resultaria em [[19 22] [43 50]]. Escolha * para medições pareadas, como preço e quantidade.
Comparações também retornam uma resposta por posição
a == b produz um array booleano. Ele não pergunta se dois arrays são iguais como objetos inteiros. Uma instrução if precisa de um valor lógico, então if a == b: falha para resultados com vários elementos. np.array_equal(a, b) testa a igualdade exata dos arrays inteiros. Para decimais aproximados, np.allclose(a, b) testa a concordância dentro de uma tolerância.
Entenda os avisos de divisão
Com as configurações padrão de erro do NumPy, a divisão de ponto flutuante por zero produz um aviso e valores especiais:
np.array([1.0, -1.0, 0.0]) / 0
# array([ inf, -inf, nan])
np.isfinite identifica resultados que não são infinitos nem NaN. Já a divisão inteira com piso por zero retorna zeros inteiros com um aviso. Esses zeros parecem finitos, então inspecione os denominadores inteiros com (d == 0).any() antes da divisão com piso. Um aviso merece atenção mesmo quando o programa continua.
Decida se deve atualizar o próprio objeto
a += value modifica o armazenamento existente e mantém seu tipo de dados. Se a for um array de inteiros, a += 0.5 gera um erro de conversão porque o resultado de ponto flutuante não pode ser armazenado segundo a regra de conversão dessa operação. a = a + 0.5 cria um resultado de ponto flutuante e faz a se referir a ele. Isso difere de atribuir um decimal a um elemento inteiro, o que pode truncar sem aviso.
Construa uma expressão com várias etapas
Para old = np.array([2.50, 4.00, 8.00]) e new = np.array([3.00, 3.00, 8.00]), (new - old) / old * 100 resulta em [20. -25. 0.]. Primeiro encontre cada variação, depois divida-a pelo valor original e expresse a razão como uma porcentagem. Os sinais mostram um aumento, uma queda e nenhuma alteração. Os valores originais devem ser diferentes de zero para esse cálculo percentual.
Principais conclusões
- Operadores vetorizados calculam em arrays inteiros elemento a elemento.
*pareia entradas;@executa um produto matricial.- Comparações de arrays inteiros precisam de uma função que produza um único resultado.
- Verifique denominadores e examine avisos de divisão.
- A aritmética no próprio objeto mantém o tipo de dados do destino.
4.2 Aplicar funções universais a arrays inteiros
Uma função universal aplica um cálculo separadamente em cada posição de um array. Essas funções estendem a vetorização além da aritmética comum, incluindo raízes, logaritmos, arredondamento, comparações e outras operações numéricas.
Escolha uma função adequada para arrays
Funções universais unárias recebem uma entrada. np.sqrt(np.array([1, 4, 9])) resulta em [1. 2. 3.], e np.abs(np.array([-2, 3])) resulta em [2 3]. np.exp é a função exponencial, np.log é o logaritmo natural e np.log10 é o logaritmo de base 10. Por exemplo, np.exp(0) é 1,0 e np.log10(1000) é 3,0.
O módulo math do Python opera em números individuais. math.sqrt(np.array([1, 4])) não consegue calcular ambas as raízes e gera um erro de tipo. Use a versão do NumPy para arrays numéricos. Operadores também chamam funções universais: a + b corresponde a np.add(a, b) e a * b a np.multiply(a, b).
Compare valores correspondentes ou reduza um array inteiro
Funções universais binárias recebem duas entradas. np.maximum([1, 5, 3], [4, 2, 6]) resulta em [4 5 6], escolhendo o maior valor em cada posição. np.minimum escolhe o menor, e np.power eleva bases correspondentes a potências.
np.maximum(x, 0) define entradas negativas como zero em um novo resultado. É diferente de np.max(x), uma agregação que retorna um único maior valor. Para [1, 5, 3], max resulta em 5; maximum precisa de outra entrada e mantém a estrutura elemento a elemento.
Arredonde com a regra desejada
| Função | Regra | Resultado para −2,5 |
|---|---|---|
np.floor | Para baixo, em direção ao infinito negativo | −3,0 |
np.ceil | Para cima, em direção ao infinito positivo | −2,0 |
np.trunc | Em direção a zero | −2,0 |
np.round | Para o mais próximo; valores exatamente na metade vão para o par | −2,0 |
np.round(x, 2) mantém duas casas decimais. Valores exatamente na metade seguem a regra do par: np.round([0.5, 1.5, 2.5]) resulta em [0. 2. 2.]. A aproximação binária pode afetar valores decimais que parecem estar exatamente na metade, então interprete os decimais exibidos considerando sua representação em ponto flutuante.
Inspecione valores fora do domínio de uma função
Para entradas reais de ponto flutuante, np.sqrt(-1.0) retorna NaN com um aviso, enquanto np.log(0.0) retorna infinito negativo com um aviso nas configurações padrão de erro. Ao contrário de math.sqrt(-1), essas chamadas normalmente não interrompem a execução com uma exceção de domínio. Verifique as entradas quando a operação matemática exigir uma faixa restrita. np.isnan marca NaN; np.isfinite marca valores que não são NaN nem infinitos; np.isclose compara valores com uma tolerância.
Combine funções universais em um cálculo útil
Para os arrays de coordenadas x = np.array([3, 5, 8]) e y = np.array([4, 12, 15]), calcule a distância da origem com np.sqrt(x ** 2 + y ** 2). Elevar ao quadrado resulta em [9 25 64] e [16 144 225]; somar resulta em [25 169 289]; as raízes são [5. 13. 17.]. np.hypot(x, y) calcula essas distâncias diretamente.
Principais conclusões
- Funções universais executam operações numéricas em cada posição.
- Use funções do NumPy para arrays, incluindo raízes e logaritmos.
maximumcompara posições;maxreduz valores.- Piso, teto, truncamento e arredondamento usam regras diferentes.
- Inspecione NaN e infinito após operações inválidas com valores reais.
4.3 Combinar arrays de formas diferentes por difusão
A difusão permite que arrays de formas diferentes participem de cálculos elemento a elemento. Os eixos alinhados determinam quais valores são pareados e quais são repetidos.
Compare dimensões pela direita
Alinhe as formas pelas extremidades direitas. Cada par de comprimentos de eixo deve ser igual ou ter um comprimento igual a 1. Eixos iniciais ausentes contam como comprimento 1. Um eixo de comprimento um se expande conceitualmente para corresponder ao outro comprimento; o NumPy não precisa copiar os valores de entrada repetidos.
Para (4, 3) e (3,), os últimos comprimentos coincidem em 3. A dimensão inicial ausente age como 1 e se expande para 4. O resultado é (4, 3): o vetor se aplica a cada linha. (4, 3) e (4,) falham porque os comprimentos finais 3 e 4 diferem e nenhum deles é 1. Um par incompatível gera ValueError.
Centralize na média ou padronize colunas
X = np.array([[1, 10], [2, 20], [3, 30]])
centered = X - X.mean(axis=0)
As médias das colunas são [2. 20.], de forma (2,). Elas se alinham ao último eixo de (3, 2), resultando em [[-1. -10.] [0. 0.] [1. 10.]]. Dividir o resultado centralizado por X.std(axis=0) padroniza cada coluna, produzindo aproximadamente −1,22; 0 e 1,22 ao longo de ambas as colunas. A dispersão de cada coluna deve ser diferente de zero para essa divisão.
Mantenha um eixo para cálculos por linha
Use uma tabela de notas com quatro estudantes e três provas:
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
scores.mean(axis=1) tem forma (4,). Ela não pode ser difundida como uma média por linha em relação a (4, 3). Preserve o eixo removido:
row_mean = scores.mean(axis=1, keepdims=True)
centered = scores - row_mean
row_mean agora tem forma (4, 1). Seu 4 inicial corresponde às linhas; seu 1 final se expande pelas três colunas. scores.mean(axis=1)[:, np.newaxis] cria a mesma forma. Para a linha [78, 85, 92], subtrair sua média de 85 resulta em [-7. 0. 7.].
Use a mesma regra para construir uma tabela
np.arange(1, 4)[:, np.newaxis] * np.arange(1, 5) combina (3, 1) e (4,). Ambos os arrays se expandem para a forma resultante (3, 4), produzindo [[1 2 3 4] [2 4 6 8] [3 6 9 12]].
A expansão também pode ser acidental. Uma coluna (3, 1) menos um vetor (3,) cria todas as nove diferenças entre pares, com forma (3, 3). Se você pretendia obter três diferenças correspondentes, deixe ambas as entradas com forma (3,), por exemplo com column.ravel().
Pondere cada coluna antes de somar
Para a mesma tabela de notas e w = np.array([0.2, 0.3, 0.5]), scores * w aplica os três pesos a cada linha. Somar com .sum(axis=1) resulta em [87.1 62.8 92.4 74.8]. O primeiro resultado é 15,6 + 25,5 + 46,0 = 87,1.
Principais conclusões
- Alinhe as formas pela direita; comprimentos pareados devem coincidir ou incluir 1.
- Um eixo de comprimento um controla a direção da expansão.
- Resumos de colunas geralmente se alinham diretamente com uma tabela.
- Mantenha resumos de linhas em forma de coluna com
keepdims=True. - A difusão pode criar uma tabela não intencional de pares.
- Pondere as colunas antes de reduzir os valores de cada linha.
5Resumir arrays com agregações ao longo dos eixos
Uma tabela pode produzir um total geral, um resumo por registro ou um resumo por variável. Decida qual eixo reduzir e escolha uma estatística que responda à sua pergunta. Posições, totais acumulados e postos ordenados oferecem visões diferentes dos dados. Valores ausentes e condições exigem decisões próprias, pois filtrar ou preencher pode alterar tanto as observações que contribuem quanto o significado do resultado.
5.1 Agregar um array inteiro ou ao longo de um eixo
Uma agregação combina valores em menos resultados: um total, uma média, um extremo ou uma medida de dispersão. Escolher o eixo faz parte de escolher a pergunta, pois isso determina quais grupos de valores são combinados.
Reduza o eixo que você indicar
Para uma tabela (4, 3) com quatro estudantes e três provas, uma agregação sem axis usa todos os 12 valores. scores.sum() fornece um total. scores.mean(axis=0) reduz o eixo dos estudantes e deixa três médias de provas. scores.mean(axis=1) reduz o eixo das provas e deixa quatro médias de estudantes.
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
Sua soma geral é 941. As médias das colunas são [75.5 78.5 81.25]; as médias das linhas são aproximadamente [85. 64. 91.33 73.33]. Pergunte qual eixo deve desaparecer. Dizer “o eixo 0 significa cada linha” inverte a operação: o eixo 0 combina linhas.
Escolha a quantidade a retornar
| Operação | Tipo de resultado |
|---|---|
sum, prod | Total ou produto |
mean | Média aritmética |
min, max | Valor extremo |
argmin, argmax | Posição de um extremo |
std, var | Desvio padrão ou variância |
Métodos como a.sum() e funções como np.sum(a) expressam a mesma operação básica. Os métodos do NumPy evitam o comportamento diferente das funções nativas do Python. Por exemplo, sum(scores) do Python soma os arrays das linhas para produzir totais das colunas, enquanto scores.sum() combina todas as entradas. max(scores) do Python tenta comparar linhas e gera um erro de valor lógico ambíguo.
Posições diferem de valores
scores.mean(axis=1).argmax() é 2: o terceiro estudante tem a maior média. argmax retorna a primeira posição quando há empate entre máximos. Sem um eixo em uma tabela, ele retorna um índice achatado em ordem por linhas; scores.argmax() é 8. np.unravel_index(8, scores.shape) recupera a coordenada (2, 2).
Use keepdims=True quando um resumo precisar se alinhar à tabela original. scores.sum(axis=1, keepdims=True) tem forma (4, 1), adequada para um valor de normalização por linha. Sem ele, o resultado tem forma (4,).
Mantenha totais intermediários quando a ordem importar
np.cumsum([3, 1, 4, 1, 5]) resulta em [3 4 8 9 14]. Cada posição é o total até aquele ponto. np.cumprod([1, 2, 3, 4]) resulta de modo semelhante em [1 2 6 24]. np.diff([3, 1, 4, 1, 5]) fornece as quatro variações entre vizinhos [-2 3 -3 4]. Em uma tabela, especifique axis=1 para obter totais acumulados separados ao longo das linhas.
Informe a convenção de dispersão
std e var dividem a soma dos desvios ao quadrado pelo número de valores por padrão: ddof=0. Use ddof=1 para a fórmula amostral, cujo divisor é uma unidade menor. Para [2, 4, 4, 4, 5, 5, 7, 9], a média é 5, o desvio padrão padrão é 2,0 e o desvio padrão amostral é aproximadamente 2,14. Um relatório deve deixar clara a convenção usada.
Principais conclusões
- O argumento
axisindica o eixo que está sendo reduzido. - Sem eixo indicado, obtém-se um resumo para o array inteiro.
argmineargmaxretornam posições, incluindo a primeira posição em caso de empate.keepdims=Truemantém os eixos reduzidos com comprimento 1.- Funções acumuladas mantêm resultados intermediários.
- O NumPy usa
ddof=0por padrão;ddof=1seleciona o divisor amostral. - Prefira agregações do NumPy às funções nativas do Python em arrays.
5.2 Usar medianas, percentis, ordenação e valores distintos
Resumos baseados na ordem descrevem onde os valores se encontram em uma distribuição ordenada. A ordenação também permite classificar registros, mas uma tabela exige cuidado para manter juntos os campos de cada registro.
Localize o centro e os quartis
Para x = np.array([12, 15, 11, 20, 18, 14]), a ordem crescente é [11 12 14 15 18 20]. Com seis valores, np.median(x) calcula a média dos dois centrais, 14 e 15, resultando em 14,5. Para uma quantidade ímpar, a mediana é o único valor central.
np.percentile(x, q) recebe uma porcentagem de 0 a 100. np.quantile(x, q) recebe a fração equivalente de 0 a 1. Sua interpolação linear padrão pode fornecer um valor entre observações. Para seis valores, a posição do 25º percentil, com contagem a partir de zero, é 0,25 × 5 = 1,25. Ela fica a um quarto do caminho entre 12 e 14, resultando em 12,5. Os percentis 50 e 75 são 14,5 e 17,25, então a amplitude interquartil é 4,75.
A mediana resiste mais a um valor extremo do que a média. Adicionar 200 a esses dados desloca a média de 15,0 para aproximadamente 41,4; a mediana passa de 14,5 para 15,0. Nenhuma das duas medidas descreve sozinha a distribuição inteira.
Escolha entre dados ordenados e posições de ordenação
np.sort(x) retorna uma cópia ordenada. x.sort() altera x e retorna None, então y = x.sort() não coloca valores ordenados em y. Para valores em ordem decrescente, use np.sort(x)[::-1].
Em um array de 2 dimensões, a ordenação usa o último eixo por padrão, ordenando cada linha independentemente. axis=0 ordena cada coluna independentemente. Nenhuma das operações ordena registros. Para tab = np.array([[3, 1], [1, 2], [2, 0]]), np.sort(tab, axis=0) resulta em [[1 0] [2 1] [3 2]], separando valores que originalmente pertenciam uns aos outros.
Para preservar registros, obtenha uma ordem a partir da coluna de chave e aplique-a a linhas inteiras:
order = tab[:, 0].argsort()
ranked = tab[order]
# array([[1, 2], [2, 0], [3, 1]])
A mesma ordem de índices pode reordenar vetores relacionados. Se avg = np.array([85.0, 64.0, 91.33, 73.33]) e names = np.array(['Ana', 'Ben', 'Chen', 'Dara']), order = np.argsort(avg)[::-1] ordena as médias em ordem decrescente. names[order] resulta em ['Chen' 'Ana' 'Dara' 'Ben'].
Conte valores distintos e teste a presença em uma coleção
np.unique retorna valores distintos ordenados. Com return_counts=True, também retorna as contagens correspondentes:
colors = np.array(['red', 'blue', 'red', 'green', 'blue', 'red'])
values, counts = np.unique(colors, return_counts=True)
As saídas são ['blue' 'green' 'red'] e [2 1 3]. values[counts.argmax()] encontra o valor mais frequente, 'red'. As posições das contagens correspondem às posições dos valores distintos.
np.isin(a, allowed) retorna uma máscara de presença em uma coleção. Para a = np.arange(1, 6), np.isin(a, [2, 4]) resulta em [False True False True False], pronta para selecionar esses valores ou seus registros associados.
Principais conclusões
- A mediana usa a posição ordenada e resiste a valores extremos.
- Percentis usam de 0 a 100; quantis usam de 0 a 1.
- A interpolação padrão de percentis pode resultar em um valor entre observações.
np.sortcopia;.sort()de um array altera o objeto e retornaNone.- Use posições de
argsortpara manter registros e arrays relacionados alinhados. unique(..., return_counts=True)pareia valores distintos com frequências.isinconstrói uma máscara de presença em uma coleção.
5.3 Resumir dados com valores ausentes e condições
Dados ausentes e subconjuntos filtrados precisam de uma política explícita de resumo. Um resultado numérico pode estar errado mesmo quando a operação no array é executada corretamente: um marcador pode ser contado como uma medição ou um subconjunto vazio pode ser confundido com uma média significativa.
Identifique valores ausentes antes de resumir
NaN se propaga por somas e médias comuns. Para x = np.array([3.0, np.nan, 5.0]), tanto x.sum() quanto x.mean() resultam em NaN. np.nansum(x) resulta em 8,0 e np.nanmean(x) resulta em 4,0, ignorando a posição ausente. Funções relacionadas incluem nanmax, nanmin, nanstd e nanmedian. Se todos os valores estiverem ausentes, nanmean retorna NaN com um aviso porque não restam valores observados.
Para leituras de sensor em °C:
r = np.array([21.5, np.nan, 22.1, 23.0, np.nan, 21.9])
missing = np.isnan(r)
missing.sum() é 2, missing.mean() é aproximadamente 0,33, e r[~missing] mantém quatro leituras. np.nanmean(r) é 22,125, usando apenas esses quatro valores. A comparação r == np.nan não marcaria as leituras ausentes.
Converta primeiro os códigos usados como marcadores
Um número como −999 pode representar dados ausentes em um sistema de entrada. O NumPy o trata como uma medição real até que você o substitua:
v = np.array([12, -999, 15, -999, 9]).astype(float)
v[v == -999] = np.nan
np.nanmean(v) # 12.0
Converta primeiro para ponto flutuante porque um array de inteiros não pode armazenar NaN. Essa substituição só é adequada quando −999 está definido como código de valor ausente para esses dados.
O preenchimento altera a distribuição
Substituir temperaturas ausentes por zero faz a média do exemplo ser 14,75, embora nenhuma medição de temperatura zero tenha sido observada. Preenchê-las com a média observada, 22,125, preserva essa média, mas reduz a dispersão aparente. Um valor preenchido é uma estimativa introduzida, então seu efeito deve fazer parte da decisão de análise.
Para uma tabela D de 2 dimensões, np.nanmean(D, axis=0) resume os valores observados de cada coluna. Cada coluna pode ter uma contagem diferente. Para remover linhas que contêm qualquer valor ausente:
complete = ~np.isnan(D).any(axis=1)
clean_rows = D[complete]
A redução cria uma decisão por linha; a negação mantém linhas sem entradas ausentes. Com D = np.array([[1., 2.], [np.nan, 4.], [5., np.nan], [7., 8.]]), isso mantém [[1. 2.] [7. 8.]].
Resuma uma condição ou um grupo
Para temperaturas t, t[t > 20].mean() calcula a média apenas dos dias acima de 20 °C. Em dados agrupados, use uma máscara de rótulos correspondente: com group = np.array(['A', 'B', 'A', 'B', 'A']) e value = np.array([10, 20, 14, 26, 12]), value[group == 'A'].mean() é 12,0 e a média correspondente de B é 23,0. Percorra np.unique(group) para repetir isso para cada grupo.
Antes de resumir um subconjunto filtrado, verifique mask.any(). A média de uma seleção vazia é NaN com um aviso, enquanto sua soma é 0. Esse zero pode ser um total válido para uma seleção vazia, mas não estabelece que alguma medição estivesse presente.
Principais conclusões
- Somas e médias comuns propagam NaN; as versões que ignoram NaN o pulam.
- Converta códigos definidos como ausentes para NaN em armazenamento de ponto flutuante.
- Preencher valores ausentes altera as estatísticas.
- Testes de valores ausentes por linha podem identificar registros completos.
- Combine máscaras de rótulos ou condições com agregações.
- Verifique se um subconjunto está vazio antes de interpretar sua média.
6Gerar números aleatórios e executar simulações
Arrays aleatórios permitem amostragem reproduzível e experimentos práticos. Crie um objeto Generator com semente definida, escolha uma distribuição e uma forma de saída e preserve as relações entre registros ao embaralhar ou dividir dados. Em uma simulação, explicite a estrutura do ensaio antes de calcular eventos ou posições acumuladas. Compare os resultados com casos exatos simples e separe a variação amostral comum de erros no código.
6.1 Obter amostras aleatórias reproduzíveis com um objeto Generator
Um gerador de números aleatórios permite amostragem, embaralhamento e simulação. Uma semente torna o estado inicial reproduzível, para que você possa executar novamente uma análise enquanto investiga sua lógica.
Crie um objeto Generator e reutilize-o
rng = np.random.default_rng(42)
O NumPy recomenda essa interface Generator para código novo. Seu gerador de bits padrão é PCG64. Sem uma semente, default_rng() obtém entropia nova do sistema operacional. Chamadas antigas como np.random.seed e np.random.rand usam um estado global compartilhado; objetos Generator permitem que uma análise gerencie diretamente seu próprio estado.
Valores pseudoaleatórios vêm de um algoritmo determinístico. O mesmo estado inicial e a mesma sequência de chamadas reproduzem a sequência no mesmo ambiente. Cada sorteio avança o estado. Criar um novo objeto Generator com a semente 42 em cada passagem de um laço reinicia a sequência, repetindo os mesmos sorteios iniciais em vez de continuá-la. Registre a versão do NumPy e o código, além da semente, pois a compatibilidade da sequência não é garantida entre versões ou em todos os ambientes. Para senhas ou tokens de segurança, use o módulo secrets do Python.
Escolha uma distribuição e uma forma de saída
| Chamada | Significado |
|---|---|
rng.random(5) | Cinco decimais de 0 inclusivo a 1 exclusivo |
rng.uniform(2, 8, size=5) | Cinco sorteios uniformes no intervalo de 2 a 8 |
rng.integers(1, 7, size=10) | Dez inteiros de 1 a 6 |
rng.normal(loc=170, scale=10, size=(3, 4)) | Uma amostra de 3 por 4 de uma distribuição normal |
size pode ser uma quantidade de elementos ou uma tupla de forma. Para normal, loc é a média da distribuição e scale é seu desvio padrão. Portanto, uma variância de 100 precisa de scale=10. A média e o desvio padrão reais de uma pequena amostra não precisam coincidir exatamente com os parâmetros da distribuição.
Para sorteios de inteiros, o limite superior é excluído por padrão. Um dado precisa de integers(1, 7), pois integers(1, 6) não pode sortear 6. integers(1, 6, endpoint=True) inclui o limite superior e também representa um dado.
Obtenha amostras com ou sem reposição
rng.choice(['heads', 'tails'], size=5) faz cinco sorteios com reposição. Um valor pode aparecer várias vezes. Para posições amostradas distintas, use replace=False; solicitar mais posições do que a população possui gera ValueError. As probabilidades podem ser fornecidas como p=[0.7, 0.3], na mesma ordem dos valores, e devem somar 1.
A amostragem sem reposição impede a seleção de uma posição de entrada duas vezes. Se a própria entrada contiver valores duplicados, valores iguais ainda poderão aparecer na amostra.
Embaralhe registros sem separar seus campos
rng.shuffle(a) reorganiza o array existente e retorna None. rng.permutation(a) retorna uma cópia embaralhada. rng.permutation(10) fornece os inteiros de 0 a 9 em ordem aleatória, úteis como índices de linhas.
Para um array de 2 dimensões, o eixo padrão é 0: linhas completas se movem juntas. Isso mantém alinhados os campos de cada observação. Para embaralhar dois arrays relacionados de forma consistente, gere uma permutação dos índices de registros compartilhados e aplique-a a ambos.
Principais conclusões
- Crie um objeto Generator com semente definida uma vez e reutilize seu estado à medida que ele avança.
- A reprodutibilidade depende da semente, das chamadas e do ambiente numérico.
- Sorteios de inteiros excluem o limite superior, a menos que se use
endpoint=True. - O
scaleda distribuição normal é o desvio padrão, não a variância. choicefaz amostragem com reposição por padrão.shufflealtera o objeto;permutationretorna um resultado embaralhado.
6.2 Executar simulações vetorizadas
Uma simulação vetorizada representa ensaios repetidos como arrays, aplica a regra do evento a esses arrays e resume os resultados. A forma do array deve mostrar o que um ensaio contém.
Transforme um evento em uma proporção
rng = np.random.default_rng(42)
rolls = rng.integers(1, 7, size=100_000)
estimate = (rolls == 6).mean()
A máscara é verdadeira uma vez para cada 6 observado. Sua média estima a probabilidade desse evento, próxima de 1/6, ou aproximadamente 0,1667. rolls.mean() responde a uma pergunta diferente: a média das faces do dado, próxima de 3,5. Uma semente fixa repete uma estimativa; ela não torna essa estimativa exata.
A vetorização evita trabalho no nível do Python para cada sorteio, muitas vezes tornando simulações grandes muito mais rápidas que um laço. O ganho de velocidade depende do cálculo, do tamanho do array e do computador, então não é uma propriedade fixa do evento.
Use uma linha por ensaio com vários valores
Para simular dois dados em cada ensaio:
dice = rng.integers(1, 7, size=(100_000, 2))
totals = dice.sum(axis=1)
p_seven = (totals == 7).mean()
A tabela tem 100.000 linhas de ensaios e duas colunas de dados. Reduzir o eixo 1 produz um total por ensaio. Seis dos 36 pares ordenados igualmente prováveis somam 7, então a probabilidade estimada deve ficar próxima de 6/36. Reduzir o eixo 0 forneceria dois totais para todos os ensaios e perderia o evento de cada ensaio.
Simulações maiores ainda variam
Para ensaios independentes, o erro padrão de uma proporção estimada é:
Aqui é a probabilidade do evento e é a quantidade de ensaios. Para o 6 de um dado com 100.000 ensaios, ele é aproximadamente 0,0012. Uma aproximação normal coloca cerca de 95% das estimativas a uma distância máxima de 0,0023 de 1/6. Aumentar a quantidade de ensaios por um fator de 100 reduz o erro padrão por um fator de 10. Mais sorteios não corrigem um evento codificado incorretamente.
Construa e inspecione um passeio aleatório
steps = rng.choice([-1, 1], size=1000) sorteia passos para a esquerda ou para a direita. walk = steps.cumsum() fornece a posição após cada passo. Seu máximo e mínimo localizam as posições extremas visitadas. Para encontrar o primeiro ponto a pelo menos 10 unidades do início:
hit = np.abs(walk) >= 10
if hit.any():
step_count = hit.argmax() + 1
argmax localiza a primeira entrada verdadeira, mas também retorna 0 quando todas as entradas são falsas. A verificação com any() distingue uma passagem real de nenhuma passagem. Some 1 porque a posição 0 do array é a posição após o passo 1.
Para muitos passeios, rng.choice([-1, 1], size=(5000, 1000)).cumsum(axis=1) acumula separadamente ao longo de cada linha. walks[:, -1] seleciona todas as posições finais; sua média fica próxima de 0 e seu desvio padrão próximo da raiz quadrada de 1.000, aproximadamente 31,6.
Use permutações e verificações exatas
Uma divisão aleatória de 100 registros pode usar idx = rng.permutation(100), seguido de data[idx[:80]] e data[idx[80:]]. As duas fatias sem sobreposição de uma permutação atribuem cada registro exatamente uma vez. Para uma simulação, compare um caso simples com uma resposta exata, como a média 3,5 de um dado, antes de confiar em resultados mais complicados.
Principais conclusões
- Represente claramente um ensaio na forma do array.
- Uma média booleana estima a probabilidade de um evento.
- Reduza dentro dos ensaios antes de combinar resultados entre ensaios.
- O erro padrão diminui com a raiz quadrada da quantidade de ensaios.
- Verifique se houve uma passagem antes de usar
argmaxpara localizar a primeira. - Uma permutação pode produzir divisões aleatórias de registros sem sobreposição.
- Valide a lógica da simulação com um caso simples e exato.
Exercícios resolvidos de Arrays NumPy e computação vetorizada
1Construa um array de medições confiável
14 passos
- 1IntroduçãoPlaneje os registros e as medições
Uma tabela de medições exige duas decisões antes de qualquer cálculo: o que cada eixo representa e que tipo de valores deve ser armazenado. Vamos construir uma pequena tabela, inspecionar sua forma e escolher métodos de criação e conversão que preservem os dados.
Mantenha
import numpy as npno início do script. O nomenpdá acesso às funções do NumPy usadas ao longo dos exemplos. - 2ExplicaçãoLeia uma tabela por seus eixos
Crie
a = np.array([[2, 4, 6], [3, 5, 7]]). A sequência externa fornece duas linhas; cada sequência interna fornece três valores.a.shapeé(2, 3),a.ndimé 2 ea.sizeé 6. A forma descreve a disposição, ndim conta os eixos e size conta todas as entradas. Se cada linha for um registro, essa tabela contém dois registros com três medições cada. - 3Ideia-chaveNúmeros iguais de elementos podem ter estruturas diferentes
Um vetor de comprimento seis tem forma
(6,). Uma tabela com uma linha tem forma(1, 6), e uma tabela com uma coluna tem forma(6, 1). Cada uma contém seis valores, mas apenas as duas últimas têm eixos de linha e coluna separados.A vírgula final em
(6,)indica uma tupla de uma entrada. É uma informação útil: o vetor tem um eixo, então não tem uma direção de linha separada para transpor em uma coluna. - 4DesafioPreveja a multiplicação antes de executá-la
Quais são os resultados de
[2, 5] * 2enp.array([2, 5]) * 2?---reveal---
A lista se torna
[2, 5, 2, 5]. O array se torna[4 10]. Listas repetem seu conteúdo na multiplicação por inteiro; arrays numéricos multiplicam os valores em cada posição. O array mantém sua forma, o que o torna adequado para aplicar um cálculo a cada valor registrado. - 5ExemploReserve uma tabela com forma conhecida
Suponha que duas estações fornecerão quatro leituras de precipitação em milímetros cada. Crie
rain = np.zeros((2, 4))e depois atribuarain[0] = [4.0, 0.0, 3.5, 6.0].A tupla
(2, 4)é um único argumento de forma. Zeros usa armazenamento de ponto flutuante por padrão, então a leitura 3,5 é preservada. Reservar a forma final uma vez evita copiar repetidamente um array crescente conforme as leituras chegam. - 6DicaEscolha conscientemente o preenchimento inicial
Use
zerosquando zeros iniciais tiverem significado,onespara uns efull(shape, value)para outro valor repetido. Seus nomes descrevem o conteúdo inicial.emptyapenas reserva armazenamento. Seus valores iniciais não estão prontos para uso, então cada entrada deve ser preenchida antes de ser lida. Uma tabela preenchida com zeros é mais fácil de inspecionar enquanto você escreve código que atribuirá apenas algumas de suas entradas. - 7ExplicaçãoConte pontos e intervalos separadamente
Para posições de medição de 0 m a 2 m em intervalos de 0,5 m, há cinco pontos e quatro intervalos.
np.linspace(0, 2, 5)cria esses pontos e inclui ambos os extremos.np.arange(0, 2, 0.5)usa um passo e exclui o valor final, então omite 2 m. O arredondamento de ponto flutuante também pode tornar grades decimais dearangeinesperadas; uselinspacequando a exigência for a quantidade de pontos. - 8DesafioEscolha uma grade a partir de seus extremos
Uma varredura exige nove posições igualmente espaçadas de 0 cm a 4 cm, incluindo ambos os extremos. Qual chamada de criação é adequada e qual é o espaçamento?
---reveal---
Use
np.linspace(0, 4, 9). Nove pontos formam oito intervalos ao longo de 4 cm, então o espaçamento é 0,5 cm. Um terceiro argumento de 8 solicitaria oito pontos, deixando apenas sete intervalos e produzindo um espaçamento diferente entre as leituras. - 9ExplicaçãoInspecione o tipo de dados inferido
np.array([1, 2.5])se torna de ponto flutuante porque um único tipo de dados compartilhado deve comportar ambos os valores. Misturar um número com texto pode transformar todos os valores em texto, fazendo a aritmética falhar.Inspecione
a.dtypequando os valores não se comportarem como esperado.a.itemsizeinforma os bytes de armazenamento por elemento; multiplicá-lo pora.sizefornecea.nbytes, o total de bytes ocupados pelos elementos. - 10ExemploObserve uma atribuição descartar decimais
Comece com
counts = np.array([2, 4, 6])e executecounts[0] = 3.8. A primeira entrada se torna 3 porque o armazenamento existente permanece inteiro.Para preservar decimais posteriores, crie primeiro um armazenamento de ponto flutuante com
values = counts.astype(float).astypecria uma cópia convertida. Ele não altera o tipo de dados do array original nem recupera informações fracionárias que uma atribuição anterior já descartou. - 11Ideia-chaveConversão e arredondamento são operações separadas
np.array([2.8, -2.8]).astype(int)resulta em[2 -2]: o truncamento se move em direção a zero.np.roundarredonda para o mais próximo, com valores exatamente na metade indo para o par, então 2,5 é arredondado para 2,0.Tipos inteiros pequenos apresentam outro risco. Um
uint8não pode armazenar 260, então operações aritméticas em arrays como 250 mais 10 podem retornar ao outro extremo e resultar em 4. Amplie o tipo de dados antes de calcular valores que possam exceder sua faixa. - 12DesafioPreserve uma leitura ausente
Você tem
a = np.array([5, 7, 9])e precisa marcar sua leitura do meio como ausente. Que preparação o array precisa antes de atribuir NaN?---reveal---
Converta para armazenamento de ponto flutuante:
a = a.astype(float)e depois definaa[1] = np.nan. O armazenamento de inteiros não pode representar NaN. O resultado é[5. nan 9.]; substituir por zero registraria um valor numérico em vez de marcar uma medição ausente. - 13DesafioCombine a criação com uma atualização posterior
Você cria
template = np.array([1, 2])e depois precisa de um array com a mesma forma cujos valores possam incluir 1,5 e NaN. Que escolha de criação mantém esses valores possíveis?---reveal---
Use um tipo de dados de ponto flutuante, por exemplo
np.zeros_like(template, dtype=float). A função like padrão herdaria o armazenamento de inteiros. A forma pode continuar(2,), enquanto escolher ponto flutuante permite tanto a medição fracionária quanto o marcador de valor ausente. - 14RecapitulaçãoInspecione a estrutura antes de calcular
No próximo array que você criar, inspecione
shape,sizeedtypeantes de aplicar operações aritméticas. Verifique se cada eixo representa o grupo pretendido de valores e se o armazenamento pode comportar as medições que você atribuirá.Escolha conscientemente uma quantidade de pontos ou um passo ao gerar uma grade. Se valores decimais ou NaN aparecerem, planeje o armazenamento de ponto flutuante antes de escrever esses valores no array.
2Selecione registros e controle o que as edições alteram
16 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoPergunte quais valores pertencem ao resultado
- 2ExplicaçãoAcompanhe início, fim e passo
- 3ExemploSelecione linhas e colunas em uma expressão
- 4DesafioMantenha um eixo de coluna
- 5ExemploAcompanhe uma escrita por meio de uma visão
- 6DicaTorne a independência explícita
- 7ExplicaçãoPareie coordenadas ou escolha um bloco
- 8DesafioDistinga uma cópia de uma atribuição direta
- 9ExplicaçãoTransforme uma condição em seleção
- 10ExemploCombine os limites de um intervalo
- 11Ideia-chaveConte eventos ou calcule a média de seus valores
- 12ExemploEscolha entre substituição e filtragem
- 13DesafioMantenha linhas completas
- 14DicaEncontre NaN sem usar igualdade
- 15DesafioAtualize registros selecionados independentemente
- 16RecapitulaçãoVerifique o alvo de cada edição
3Dê aos valores a forma e o agrupamento adequados
12 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoTorne o agrupamento visível na forma
- 2ExemploAgrupe valores consecutivos em períodos
- 3ExplicaçãoInfira uma dimensão desconhecida
- 4ExemploTroque o significado de linhas e colunas
- 5DesafioCrie uma coluna a partir de um vetor
- 6DicaEscolha o achatamento considerando a edição
- 7ExplicaçãoEstenda um eixo existente
- 8ExemploAdicione um eixo de lotes
- 9DesafioCrie duas colunas de medições
- 10ExemploDivida por limites ou quantidade de partes
- 11DesafioReconstrua uma tabela a partir de lotes de linhas
- 12RecapitulaçãoInterprete as formas como decisões sobre os dados
4Calcule em vários registros sem um laço Python
15 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoDeixe a expressão descrever o cálculo
- 2ExemploMultiplique valores pareados e calcule o total
- 3ExplicaçãoUse o operador de produto adequado
- 4DicaVerifique o destino e o denominador
- 5DesafioEscolha a referência para a variação percentual
- 6ExplicaçãoAplique funções matemáticas a arrays
- 7ExemploCalcule distâncias em etapas
- 8DesafioCompare maximum com uma redução
- 9DicaInspecione arredondamentos e valores inválidos
- 10ExplicaçãoAlinhe as formas pelas extremidades direitas
- 11ExemploMantenha as médias das linhas como uma coluna
- 12Ideia-chaveUma difusão válida pode responder à pergunta errada
- 13DesafioPreveja o resultado de uma difusão
- 14DesafioPondere medições centralizadas na média
- 15RecapitulaçãoVerifique valores, pareamento e forma de saída
5Resuma as observações que respondem à sua pergunta
15 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoEscolha a pergunta antes da estatística
- 2ExemploReduza o eixo das medições
- 3Ideia-chaveAcompanhe o que permanece após a redução
- 4ExemploDistinga posição, valor e total acumulado
- 5DesafioEscolha o divisor da variância
- 6ExemploLocalize uma mediana e um percentil
- 7DicaOrdene registros por meio de posições
- 8DesafioRecupere um rótulo a partir de sua contagem
- 9ExplicaçãoIgnore valores ausentes de forma consciente
- 10ExemploConverta um código de valor ausente antes de calcular a média
- 11Ideia-chaveO preenchimento cria observações para o cálculo
- 12ExemploCrie uma decisão de completude por linha
- 13DesafioReconheça um subconjunto vazio
- 14DesafioResuma e compare grupos
- 15RecapitulaçãoRelate o que contribuiu para cada resumo
6Execute uma simulação reproduzível dos sorteios aos resultados
14 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoDê uma forma clara a cada ensaio simulado
- 2ExplicaçãoCrie o objeto Generator uma vez
- 3ExemploDefina parâmetros de sorteios inteiros e normais
- 4DesafioEncontre o erro de repetição dos sorteios
- 5DicaEscolha a reposição e preserve os registros
- 6ExemploEstime um evento com uma máscara
- 7ExemploReduza dentro de cada ensaio com dois dados
- 8DesafioAltere o evento para qualquer um dos dados
- 9ExplicaçãoEspere variação amostral
- 10ExemploAcumule passos em uma trajetória
- 11DicaVerifique se o limite foi alcançado
- 12DesafioDivida os registros exatamente uma vez
- 13DesafioDecida o que uma execução muito maior pode corrigir
- 14RecapitulaçãoVerifique o modelo e depois sua precisão
Questões de Arrays NumPy e computação vetorizada
Conjunto 1: Interprete arrays e escolha a operação adequada10 Questões de Prática
Questão 1 de 10
Mostrar respostaOcultar resposta
(8, 5). (5, 8) inverte os papéis dos registros e das medições. Há 40 elementos no total, mas esse número não substitui a forma de dois eixos.Questão 2 de 10
Mostrar respostaOcultar resposta
np.linspace(0, 3, 7) fornece espaçamento de 0,5 m e inclui ambos os extremos. np.arange(0, 3, 0.5) para antes de 3 e fornece apenas seis pontos. Em linspace, o terceiro argumento conta pontos, não intervalos.Questão 3 de 10
np.array([4.9, -4.9]).astype(int)?Mostrar respostaOcultar resposta
astype(int) remove a parte fracionária em direção a zero, resultando em 4 e −4. O resultado [5, -5] exigiria arredondar primeiro para o número mais próximo. A divisão com piso usa uma direção diferente para valores negativos e não descreve essa conversão.Questão 4 de 10
v = np.array([2, 8, 11, 5, 14]), qual fração (v >= 8).mean() retorna?Mostrar respostaOcultar resposta
Questão 5 de 10
[batch_id, mass_kg]: d = np.array([[1, 4], [2, 9], [1, 7], [2, 5]]). Qual é a massa média dos registros do lote 1 cuja massa excede 5 kg?Mostrar respostaOcultar resposta
[1, 7] permanece, então a massa média é 7,0 kg. Uma média de 5,5 kg inclui ambos os registros do lote 1 e deixa de aplicar a condição de massa; 8,0 kg ignora a condição de lote.Questão 6 de 10
np.arange(8).reshape(2, 4).T[1]?Mostrar respostaOcultar resposta
[0, 1, 2, 3] e [4, 5, 6, 7]. A transposição transforma sua segunda coluna na linha 1, [1, 5]. Obter [2, 3] significaria reagrupar a sequência original em linhas de comprimento dois, o que é uma remodelagem, não uma troca de eixos.Questão 7 de 10
np.array([5., 8.]) e os novos preços são np.array([6., 6.]). Quais variações percentuais (new - old) / old * 100 fornece?Mostrar respostaOcultar resposta
Questão 8 de 10
Mostrar respostaOcultar resposta
cumsum(axis=1) mantém um total acumulado em cada dia em vez de retornar apenas um total por máquina.Questão 9 de 10
d = np.array([[9, 30], [2, 80], [5, 40]]). Como ordenar os registros pela primeira coluna, do menor para o maior, mantendo cada linha unida?Mostrar respostaOcultar resposta
argsort() fornece as posições das linhas na ordem 1, 2, 0. Aplicar essas posições a d move registros completos. Ordenar colunas independentemente com np.sort(d, axis=0) separaria os valores da primeira coluna dos valores da segunda coluna originalmente registrados com eles.Questão 10 de 10
Mostrar respostaOcultar resposta
Conjunto 2: Relacione seleções, formas e resumos10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
np.arange(4, 16, 5) cria?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
template = np.array([2, 4, 6]), quais valores são criados por np.full_like(template, 1.8) com o tipo de dados padrão?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
a após a = np.arange(7); b = a[1:5]; c = a[[1, 4]]; b[1] = 90; c[0] = 80?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
a = np.array([3, 6, 9, 12, 15, 18, 21]), quais valores a[1:6:2] seleciona?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
a e b têm formas (3, 2) e (3, 5). Qual é a forma de np.concatenate([a, b], axis=1)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
x = np.array([-3.5, 2.5]), qual é o resultado de np.floor(x) - np.trunc(x)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
x = np.array([6., 8.]) e y = np.array([8., 15.]) em metros, mantenha apenas pontos a no máximo 12 m da origem. Quais distâncias são mantidas?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
x = np.array([10., np.nan, 16., np.nan, 22.]), qual é a média após substituir cada NaN por zero?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
rng.choice(np.arange(5), size=6, replace=False) é chamado?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
dice contém 60.000 ensaios com três dados justos, com forma (60000, 3). Qual expressão estima a chance de um ensaio conter pelo menos um 6?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 3: Acompanhe dados em várias operações com arrays10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
a = np.array([8, 12]); a[0] = 3.7; b = a / 2?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
m = np.arange(20).reshape(4, 5), quais são a forma e os valores de m[1:3, 2:3]?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
t com forma (3, 4, 5), qual é a forma de t[1, :, 2:4]?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
v = np.arange(1, 13) são agrupadas em quatro períodos consecutivos de três horas. Após trocar os eixos de período e de posição dentro do período, qual é a primeira linha?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
np.array_split(np.arange(14), 4) produz?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
A = np.array([[2, 3], [4, 5]]), o que A * A retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
X são [2., 6.] e [8., 12.]. Cada linha precisa ter sua própria média subtraída. Qual resultado a expressão equivocada X - X.mean(axis=1) realmente fornece?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
x = np.array([1., 3., 5.]), qual é o valor de x.var(ddof=1)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
np.percentile([4, 8, 12, 20], 25)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
steps contém cinco movimentos de ±1 para um passeio. Você precisa da proporção de passeios que alcançam pelo menos 3 unidades de distância do início em algum passo registrado. Qual expressão calcula essa proporção?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 4: Diagnostique resultados que parecem plausíveis10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
a tem forma (6, 4) e itemsize == 8. Você executa b = a[::2, 1:] e depois c = b[:, ::2].copy(). Quantos bytes de armazenamento de elementos c possui?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
np.array([4, 7]) * 3 produz?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
m = np.arange(12).reshape(3, 4), qual é o resultado de m[[0, 2], [1, 3]]?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
[group, reading] em d são [[1., 6.], [2., np.nan], [1., 10.], [2., 14.], [1., np.nan]]. Como obter a média das leituras presentes no grupo 1?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
v = np.arange(5), como se comparam v.T.shape e v[:, np.newaxis].shape?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
x = np.array([-4., 2., 7.]), o que np.maximum(x, 3) produz?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
(3, 2) contém valores pareados de três registros. Um vetor offset de comprimento três fornece uma correção por registro. Você precisa adicionar cada correção aos dois valores de seu próprio registro. Qual expressão e forma de resultado são adequadas?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
values, counts = np.unique([4, 9, 4, 2, 9, 9], return_counts=True). O que values[counts.argmax()] retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
D = np.array([[2., 4.], [np.nan, 6.], [8., np.nan]]), o que np.nanmean(D, axis=0) retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
ids = np.arange(6) e um array separado de medições têm a mesma ordem de registros. Você precisa de quatro registros de treinamento e dois de teste, com identificadores e medições correspondentes e sem sobreposição. Qual plano garante isso?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 5: Combine ferramentas de arrays em análises completas10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
np.array([5, -999, 9]), em que −999 significa ausente. Você precisa da média observada após adicionar uma correção de 0,5 a cada leitura presente. Qual é o resultado correto?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
a = np.array([2, 5, 8, 11]); b = a[1:]; c = b[[0, 2]]; b[0] = 20; c[1] = 30; a[[0, 3]] = c. Qual é o valor de a depois disso?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
x = np.array([1., np.nan, 4., 7.]), você quer a proporção de valores observados que excedem 3. Qual é essa proporção?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
(2, 3). Qual forma resulta de np.stack([a, b], axis=1)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
a = np.array([3, 6]), você precisa dos valores [3.5, 6.5]. Por que a = a + 0.5 funciona, enquanto a += 0.5 gera um erro?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
X = np.array([[2., 6., 10.], [4., 8., 12.]]) é centralizado na média separadamente em cada linha. Qual resultado a expressão correta deve produzir?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
X = np.array([[3., 9.], [5., 7.], [8., 4.]]) contém duas leituras. Centralize cada linha na média, pondere a primeira coluna por 0,25 e a segunda por 0,75 e some os valores de cada linha. Qual é o resultado?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
x = np.array([7, 12, 12, 4]), qual é o valor de x.argmax()?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
[group, reading] em D são [[1., 4.], [1., np.nan], [2., 8.], [2., 10.], [2., np.nan]]. Preencha cada leitura ausente com a média observada de seu próprio grupo. Qual é a média das cinco leituras após o preenchimento?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Travou em uma questão sua? Ajuda com Tarefas
Termos-Chave
A
Achatamento
flatten copia os dados, enquanto ravel pode compartilhar os dados originais.table.flatten() quando precisar de um resultado separado de 1 dimensão cujas edições não possam alterar a tabela.Agregação (redução)
table.mean(axis=0) combina registros para fornecer uma média para cada coluna de medição.Agregação que ignora NaN
nanmean ou nanmedian.np.nanmean([5., np.nan, 9.]) retorna 7,0 ao calcular a média dos dois valores observados.Ajuste dos graus de liberdade
ddof, a quantidade subtraída do número de valores no divisor da variância ou do desvio padrão.ddof=1, o NumPy divide a soma dos desvios ao quadrado por quatro.Amostragem com reposição
rng.choice.Aritmética elemento a elemento
(2, 3) com * fornece seis produtos pareados em outro array (2, 3).Armazenamento homogêneo
np.array([2, 3.5]), a entrada inteira se torna um número de ponto flutuante para que ambos os elementos compartilhem esse tipo de armazenamento.Array multidimensional (ndarray)
(50, 3).Array não inicializado
np.empty(100) somente quando o código posterior preencher cada entrada antes que qualquer cálculo a utilize.Atribuição por indexação
data[:2, 0] = 0 substitui os valores da primeira coluna nas duas primeiras linhas da tabela.C
Centralização na média
X - X.mean(axis=0) subtrai a média de cada coluna dos valores dessa mesma coluna.Código de valor ausente
Compartilhamento de memória
np.shares_memory testa se dois arrays específicos apresentam essa sobreposição.Concatenação
(2, 4) e (5, 4) ao longo do eixo 0 cria uma tabela de sete linhas com quatro colunas.Conversão de tipo
astype retorna uma cópia convertida, e algumas conversões descartam informações.np.array([2.7, 5.1]).astype(int) converte os valores para 2 e 5 sem arredondar para o inteiro mais próximo.Coordenadas pareadas
m[[0, 2], [1, 3]] seleciona as coordenadas (0, 1) e (2, 3), não um bloco de 2 por 2.Cópia
saved = data[:3].copy() preserva um subconjunto independente para edições ou comparações posteriores.D
Desvio padrão
std() usam o divisor N por padrão; ddof=1 seleciona a fórmula amostral.Difusão (broadcasting)
(3,) a uma tabela de forma (8, 3) aplica esse vetor a cada uma das oito linhas.Dimensões compatíveis
(5, 1) e (4,) se combinam em (5, 4) porque seus eixos alinhados satisfazem a regra de compatibilidade.Distribuição normal
rng.normal.loc=100 e scale=4 usa média 100 e desvio padrão 4 para a distribuição, não variância 4.Divisão de arrays
array_split permite partes de comprimentos desiguais.np.arange(9) em [2, 6] fornece partes de comprimentos 2, 4 e 3 porque os números são limites de corte.Domínio da função
np.sqrt(-4.0) normalmente emite um aviso e retorna NaN.E
Eixo
data[:, 0] mantém todas as posições no eixo das linhas e seleciona sua primeira coluna.Eixo de comprimento um
[:, None] a um vetor de comprimento quatro cria a forma (4, 1), adequada para um valor por linha da tabela.Eixo de redução
keepdims.(6, 4) deixa a forma (6,), com um resultado por linha original.Empilhamento
(3, 5), com um vetor de entrada por linha.Empilhamento em colunas
np.column_stack para criar um registro de duas medições por pessoa.Ensaio
Erro padrão
Espaçamento linear
linspace cria essa grade a partir de seus extremos e da quantidade de pontos.Estouro de inteiro (integer overflow)
uint8 que contêm 250 e 10 retorna ao outro extremo da faixa e resulta em 4 porque esse tipo de dados não comporta 260.F
Fatia (slice)
a[2:7:2] seleciona as posições 2, 4 e 6, pulando uma posição entre os valores selecionados.Forma (shape)
(2, 6) descreve duas linhas de seis valores, enquanto a forma (12,) descreve um vetor de doze valores.Função de criação de arrays
np.full((3, 2), 8) cria três linhas de dois valores sem exigir seis entradas escritas separadamente.Função universal (ufunc)
np.sqrt(distances_squared) calcula uma raiz quadrada em cada posição sem usar math.sqrt, que opera em escalares no Python.Função universal binária
np.maximum(observed, minimum) escolhe o maior de dois valores alinhados em cada posição de saída.Função universal unária
np.abs em um vetor de erros com sinal produz um vetor contendo seus módulos.G
Gerador de números aleatórios (Generator)
default_rng e reutilizado por meio de métodos que avançam seu estado interno.rng.integers duas vezes continua a sequência; recriar rng com a mesma semente a reinicia.Í
Índice
Índice do valor máximo (argmax)
[3, 8, 8, 2], argmax retorna 1, que é uma posição, não o valor máximo 8.Índices de ordenação (argsort)
names[np.argsort(scores)] para listar nomes na ordem das pontuações sem perder o pareamento entre nome e pontuação.I
Imputação pela média
Indexação avançada por inteiros (fancy indexing)
a[[4, 1, 4]] inclui a posição 4 duas vezes e preserva a ordem de saída solicitada.Indexação booleana
data[data[:, 0] > 10] mantém linhas inteiras com base na condição aplicada à sua primeira coluna.Infinito
inf ou -inf e detectado como não finito.inf com um aviso nas configurações padrão do NumPy.L
Limitação de valores (clipping)
np.clip(readings, 10, 30) mantém valores internos e substitui leituras fora desse intervalo por 10 ou 30.Linha completa
~np.isnan(data).any(axis=1) cria uma entrada verdadeira para cada registro completo em uma tabela numérica.M
Máscara booleana
t > 25 marca os dias cuja temperatura registrada excede 25 °C.Matriz identidade
np.eye.np.eye(4) cria quatro uns na diagonal de um array de 4 por 4, com zeros nas posições restantes.Mediana
[1, 3, 6, 100] é 4,5, embora o último valor, incomumente alto, eleve bastante a média.N
Número de elementos (size)
(4, 7) tem 28 elementos, embora seu atributo ndim informe apenas dois eixos.Número de ponto flutuante
np.allclose quando pequenas diferenças de representação puderem ser toleradas.O
Operação lógica elemento a elemento
&, | ou ~ para e, ou ou negação.(x >= 2) & (x <= 8) mantém valores que atendem aos dois limites, com cada comparação entre parênteses.Operação no próprio objeto (in-place)
+= a um array de inteiros falha, enquanto uma adição comum pode criar armazenamento de ponto flutuante.Ordem por linhas
[0, 1, 2, 3, 4, 5] para (2, 3) coloca [0, 1, 2] na primeira linha.P
Padronização
(X - X.mean(axis=0)) / X.std(axis=0) padroniza colunas que têm desvios padrão diferentes de zero.Passeio aleatório
cumsum(axis=1) cria posições de passeios separados ao longo de cada linha de ensaio.Passo
np.arange.np.arange(2, 15, 4) usa um passo de 4 para criar a sequência [2 6 10 14].Percentil
Permutação
rng.permutation(n) em fatias de índices sem sobreposição para atribuir cada registro a exatamente um subconjunto.Piso
np.floor aplica esse arredondamento para baixo a cada valor de entrada.np.floor resulta em −3,0 porque −2 estaria acima do valor negativo original.Q
Quantil
np.quantile(x, 0.75) solicita a mesma posição que np.percentile(x, 75) com opções equivalentes.R
Referências ao mesmo objeto (aliasing)
b = a, a expressão b is a é verdadeira, e atribuir um valor por qualquer um dos nomes altera esse mesmo array.Remodelagem (reshape)
(4, 3) quando cada linha deve conter os três meses de um trimestre.Resumo condicional
mass[batch == 'B'].mean() calcula a média apenas das massas cujo rótulo de lote correspondente é B.S
Seleção condicional
np.where constrói um resultado escolhendo uma entrada nas posições verdadeiras e outra nas posições falsas.np.where(x < 0, 0, x) substitui valores negativos por zero em um novo resultado com a mesma forma geral da seleção.Seletor inteiro
(8, 3), data[:, 1] retorna a forma (8,) após remover o eixo da coluna.Semente
np.random.default_rng(17) no início fornece um ponto de partida reproduzível para a análise.Sequência pseudoaleatória
Simulação
Soma acumulada
np.cumsum([2, 5, 1]) resulta em [2, 7, 8], útil para acompanhar um saldo conforme as entradas se acumulam.Soma ponderada
(scores * weights).sum(axis=1) cria um resultado ponderado para cada linha quando os pesos se alinham às colunas.T
Tempo de primeira passagem
Teto
np.ceil aplica esse arredondamento para cima aos valores de um array.np.ceil resulta em −2,0, enquanto para 2,3 resulta em 3,0.Tipo de dados (dtype)
data.dtype pode revelar que um rótulo de texto isolado fez valores aparentemente numéricos serem armazenados como strings.Transposição
(2, 5) resulta na forma (5, 2), com cada coluna antiga se tornando uma linha.Truncamento
astype(int) resulta em −7; aplicar floor resultaria em −8.V
Valor não numérico (NaN)
[4.0, np.nan, 8.0] exigem armazenamento de ponto flutuante, e np.isnan identifica a posição ausente.Valores distintos
np.unique os retorna ordenados e também pode retornar suas contagens correspondentes de ocorrências.Vetorização
price * quantity calcula cada total por item sem um laço Python separado sobre os itens.Visão (view)
b = a[1:4], definir b[0] = 50 altera a[1] porque a fatia básica compartilha dados.Sobre esta aula
Crie seus próprios Materiais de Estudo
Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.