Manipulação de dados - III¶
Agregação e agrupamento¶
Agregando informações de linhas ou colunas¶
Para agregar informações (p.ex. somar, tomar médias etc.) de linhas ou colunas podemos utilizar alguns métodos específicos já existentes em DataFrames e Series, tais como sum
, mean
, cumsum
e aggregate
(ou equivalentemente agg
):
import pandas as pd
import numpy as np
dados_covid_PB = pd.read_csv('https://superset.plataformatarget.com.br/superset/explore_json/?form_data=%7B%22slice_id%22%3A1550%7D&csv=true',
sep=',', index_col=0)
dados_covid_PB.agg(lambda vetor: np.sum(vetor))[['casosNovos','obitosNovos']].astype('int')
casosNovos 440037
obitosNovos 9294
dtype: int64
Podemos conferir esta agregação resultante com o número de casos acumulados e óbitos acumulados
dados_covid_PB.head()
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2021-09-26 | 441155 | 134 | 484336 | 333751 | 9294 | 2.0 | 0.0211 |
2021-09-25 | 441021 | 165 | 484331 | 333441 | 9292 | 2.0 | 0.0211 |
2021-09-24 | 440856 | 225 | 484301 | 332845 | 9290 | 3.0 | 0.0211 |
2021-09-23 | 440631 | 203 | 484276 | 332540 | 9287 | 3.0 | 0.0211 |
2021-09-22 | 440428 | 297 | 484265 | 331958 | 9284 | 6.0 | 0.0211 |
Isto também pode ser obtido utilizando o método sum
de DataFrames e Series:
dados_covid_PB[['casosNovos','obitosNovos']].sum()
casosNovos 440037.0
obitosNovos 9294.0
dtype: float64
Podemos recriar a coluna 'obitosAcumulados'
com o método cumsum
(soma cumulativa):
dados_covid_PB.obitosNovos.sort_index().cumsum()
data
2020-03-16 0.0
2020-03-17 0.0
2020-03-18 0.0
2020-03-19 0.0
2020-03-20 0.0
...
2021-09-22 9284.0
2021-09-23 9287.0
2021-09-24 9290.0
2021-09-25 9292.0
2021-09-26 9294.0
Name: obitosNovos, Length: 559, dtype: float64
Selecionando entradas distintas¶
Para selecionar entradas distintas utilizamos o método drop_duplicate
. Aqui, para exemplificar, vamos utilizar o banco de dados oficial sobre COVID no Brasil:
# pode levar um tempo para ler...
covid_BR = pd.read_excel('../database/HIST_PAINEL_COVIDBR_18jul2020.xlsx')
covid_BR.tail(3)
Unnamed: 0 | regiao | estado | municipio | coduf | codmun | codRegiaoSaude | nomeRegiaoSaude | data | semanaEpi | populacaoTCU2019 | casosAcumulado | casosNovos | obitosAcumulado | obitosNovos | Recuperadosnovos | emAcompanhamentoNovos | interior/metropolitana | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
629803 | 629803 | Centro-Oeste | DF | Brasília | 53 | 530010.0 | 53001.0 | DISTRITO FEDERAL | 2020-07-16 | 29 | 3015268 | 77621 | 2242 | 1037 | 36 | NaN | NaN | 1.0 |
629804 | 629804 | Centro-Oeste | DF | Brasília | 53 | 530010.0 | 53001.0 | DISTRITO FEDERAL | 2020-07-17 | 29 | 3015268 | 79400 | 1779 | 1060 | 23 | NaN | NaN | 1.0 |
629805 | 629805 | Centro-Oeste | DF | Brasília | 53 | 530010.0 | 53001.0 | DISTRITO FEDERAL | 2020-07-18 | 29 | 3015268 | 81163 | 1763 | 1075 | 15 | NaN | NaN | 1.0 |
# resumo da tabela
covid_BR.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 629806 entries, 0 to 629805
Data columns (total 18 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Unnamed: 0 629806 non-null int64
1 regiao 629806 non-null object
2 estado 629661 non-null object
3 municipio 623352 non-null object
4 coduf 629806 non-null int64
5 codmun 625746 non-null float64
6 codRegiaoSaude 623352 non-null float64
7 nomeRegiaoSaude 623352 non-null object
8 data 629806 non-null object
9 semanaEpi 629806 non-null int64
10 populacaoTCU2019 627412 non-null object
11 casosAcumulado 629806 non-null int64
12 casosNovos 629806 non-null int64
13 obitosAcumulado 629806 non-null int64
14 obitosNovos 629806 non-null int64
15 Recuperadosnovos 91 non-null float64
16 emAcompanhamentoNovos 91 non-null float64
17 interior/metropolitana 623352 non-null float64
dtypes: float64(5), int64(7), object(6)
memory usage: 86.5+ MB
# todos os estados únicos
covid_BR.estado.drop_duplicates().array
<PandasArray>
[ nan, 'RO', 'AC', 'AM', 'RR', 'PA', 'AP', 'TO', 'MA', 'PI', 'CE', 'RN', 'PB',
'PE', 'AL', 'SE', 'BA', 'MG', 'ES', 'RJ', 'SP', 'PR', 'SC', 'RS', 'MS', 'MT',
'GO', 'DF']
Length: 28, dtype: object
# ordena alfabeticamente
covid_BR.estado.drop_duplicates().dropna().sort_values().array
<PandasArray>
['AC', 'AL', 'AM', 'AP', 'BA', 'CE', 'DF', 'ES', 'GO', 'MA', 'MG', 'MS', 'MT',
'PA', 'PB', 'PE', 'PI', 'PR', 'RJ', 'RN', 'RO', 'RR', 'RS', 'SC', 'SE', 'SP',
'TO']
Length: 27, dtype: object
Agrupando dados por valores em colunas e agregando os resultados¶
Vamos determinar uma coluna para agrupar. Consideraremos o DataFrame covid_BR
e selecionaremos os estados PB, PE, RJ e SP para realizar análises agrupando os resultados por estados.
covid_BR.query('estado in ["PB", "PE", "RJ", "SP"]')
Unnamed: 0 | regiao | estado | municipio | coduf | codmun | codRegiaoSaude | nomeRegiaoSaude | data | semanaEpi | populacaoTCU2019 | casosAcumulado | casosNovos | obitosAcumulado | obitosNovos | Recuperadosnovos | emAcompanhamentoNovos | interior/metropolitana | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1740 | 1740 | Nordeste | PB | NaN | 25 | NaN | NaN | NaN | 2020-02-25 | 9 | 4018127 | 0 | 0 | 0 | 0 | NaN | NaN | NaN |
1741 | 1741 | Nordeste | PB | NaN | 25 | NaN | NaN | NaN | 2020-02-26 | 9 | 4018127 | 0 | 0 | 0 | 0 | NaN | NaN | NaN |
1742 | 1742 | Nordeste | PB | NaN | 25 | NaN | NaN | NaN | 2020-02-27 | 9 | 4018127 | 0 | 0 | 0 | 0 | NaN | NaN | NaN |
1743 | 1743 | Nordeste | PB | NaN | 25 | NaN | NaN | NaN | 2020-02-28 | 9 | 4018127 | 0 | 0 | 0 | 0 | NaN | NaN | NaN |
1744 | 1744 | Nordeste | PB | NaN | 25 | NaN | NaN | NaN | 2020-02-29 | 9 | 4018127 | 0 | 0 | 0 | 0 | NaN | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
448655 | 448655 | Sudeste | SP | Estiva Gerbi | 35 | 355730.0 | 35141.0 | BAIXA MOGIANA | 2020-07-14 | 29 | 11304 | 62 | 6 | 3 | 1 | NaN | NaN | 0.0 |
448656 | 448656 | Sudeste | SP | Estiva Gerbi | 35 | 355730.0 | 35141.0 | BAIXA MOGIANA | 2020-07-15 | 29 | 11304 | 65 | 3 | 3 | 0 | NaN | NaN | 0.0 |
448657 | 448657 | Sudeste | SP | Estiva Gerbi | 35 | 355730.0 | 35141.0 | BAIXA MOGIANA | 2020-07-16 | 29 | 11304 | 70 | 5 | 3 | 0 | NaN | NaN | 0.0 |
448658 | 448658 | Sudeste | SP | Estiva Gerbi | 35 | 355730.0 | 35141.0 | BAIXA MOGIANA | 2020-07-17 | 29 | 11304 | 75 | 5 | 4 | 1 | NaN | NaN | 0.0 |
448659 | 448659 | Sudeste | SP | Estiva Gerbi | 35 | 355730.0 | 35141.0 | BAIXA MOGIANA | 2020-07-18 | 29 | 11304 | 75 | 0 | 4 | 0 | NaN | NaN | 0.0 |
130768 rows × 18 columns
Inspecionando o conjunto de dados, observamos que os dados para estado são apresentados com o valor NaN
para codmun
e quando codmun
possui um valor diferente de NaN
, o resultado é apenas para o município do código em questão.
Como estamos interessados nos valores por estado, vamos selecionar apenas os dados com codmun
contendo NaN
.
covid_estados = covid_BR.query('estado in ["PB", "PE", "RJ", "SP"]')
covid_apenas_estados = covid_estados.loc[covid_estados['codmun'].isna()]
Vamos agora selecionar apenas as colunas de interesse. Para tanto, vejamos os nomes das colunas:
covid_apenas_estados.columns
Index(['Unnamed: 0', 'regiao', 'estado', 'municipio', 'coduf', 'codmun',
'codRegiaoSaude', 'nomeRegiaoSaude', 'data', 'semanaEpi',
'populacaoTCU2019', 'casosAcumulado', 'casosNovos', 'obitosAcumulado',
'obitosNovos', 'Recuperadosnovos', 'emAcompanhamentoNovos',
'interior/metropolitana'],
dtype='object')
covid_apenas_estados = covid_apenas_estados[['estado', 'data', 'casosNovos', 'obitosNovos']]
A data parece ser o index natural, já que o index atual não representa nada. Observe que teremos index repetidos, pois teremos as mesmas datas em estados diferentes.
covid_apenas_estados
estado | data | casosNovos | obitosNovos | |
---|---|---|---|---|
1740 | PB | 2020-02-25 | 0 | 0 |
1741 | PB | 2020-02-26 | 0 | 0 |
1742 | PB | 2020-02-27 | 0 | 0 |
1743 | PB | 2020-02-28 | 0 | 0 |
1744 | PB | 2020-02-29 | 0 | 0 |
... | ... | ... | ... | ... |
3040 | SP | 2020-07-14 | 12000 | 417 |
3041 | SP | 2020-07-15 | 6569 | 316 |
3042 | SP | 2020-07-16 | 8872 | 398 |
3043 | SP | 2020-07-17 | 5367 | 339 |
3044 | SP | 2020-07-18 | 4612 | 270 |
580 rows × 4 columns
covid_apenas_estados = covid_apenas_estados.set_index('data')
covid_apenas_estados
estado | casosNovos | obitosNovos | |
---|---|---|---|
data | |||
2020-02-25 | PB | 0 | 0 |
2020-02-26 | PB | 0 | 0 |
2020-02-27 | PB | 0 | 0 |
2020-02-28 | PB | 0 | 0 |
2020-02-29 | PB | 0 | 0 |
... | ... | ... | ... |
2020-07-14 | SP | 12000 | 417 |
2020-07-15 | SP | 6569 | 316 |
2020-07-16 | SP | 8872 | 398 |
2020-07-17 | SP | 5367 | 339 |
2020-07-18 | SP | 4612 | 270 |
580 rows × 3 columns
Agrupando com o método groupby¶
Podemos escolher uma (ou mais colunas, incluindo o índice) para agrupar os dados. Ao agruparmos os dados, receberemos um objeto do tipo DataFrameGroupBy
. Para vermos os resultados, devemos agregar os valores:
covid_estados_agrupado = covid_apenas_estados.groupby('estado')
covid_estados_agrupado.sum().rename({'casosNovos':'Casos Totais', 'obitosNovos':'Obitos Totais'},axis=1)
Casos Totais | Obitos Totais | |
---|---|---|
estado | ||
PB | 66971 | 1477 |
PE | 78509 | 5928 |
RJ | 135230 | 11919 |
SP | 412027 | 19647 |
Podemos agrupar por mais de uma coluna. Vamos fazer dois grupos. grupo_1 formado por PB e PE e grupo_2 formado por RJ e SP. Em seguida, vamos agrupar por grupo e por data:
covid_estados_grupos = covid_apenas_estados.copy()
col_grupos = covid_estados_grupos.estado.map(lambda estado: 'grupo_1' if estado in ['PB','PE']
else 'grupo_2')
covid_estados_grupos['grupo'] = col_grupos
covid_estados_grupos
estado | casosNovos | obitosNovos | grupo | |
---|---|---|---|---|
data | ||||
2020-02-25 | PB | 0 | 0 | grupo_1 |
2020-02-26 | PB | 0 | 0 | grupo_1 |
2020-02-27 | PB | 0 | 0 | grupo_1 |
2020-02-28 | PB | 0 | 0 | grupo_1 |
2020-02-29 | PB | 0 | 0 | grupo_1 |
... | ... | ... | ... | ... |
2020-07-14 | SP | 12000 | 417 | grupo_2 |
2020-07-15 | SP | 6569 | 316 | grupo_2 |
2020-07-16 | SP | 8872 | 398 | grupo_2 |
2020-07-17 | SP | 5367 | 339 | grupo_2 |
2020-07-18 | SP | 4612 | 270 | grupo_2 |
580 rows × 4 columns
Agora vamos agrupar e agregar:
covid_grupo_agrupado = covid_estados_grupos.groupby(['grupo','data'])
covid_grupo_agrupado.sum()
casosNovos | obitosNovos | ||
---|---|---|---|
grupo | data | ||
grupo_1 | 2020-02-25 | 0 | 0 |
2020-02-26 | 0 | 0 | |
2020-02-27 | 0 | 0 | |
2020-02-28 | 0 | 0 | |
2020-02-29 | 0 | 0 | |
... | ... | ... | ... |
grupo_2 | 2020-07-14 | 12778 | 567 |
2020-07-15 | 8196 | 449 | |
2020-07-16 | 8996 | 490 | |
2020-07-17 | 6024 | 409 | |
2020-07-18 | 4612 | 270 |
290 rows × 2 columns
Mesclando DataFrames¶
Vamos agora ver algumas formas de juntar dois ou mais DataFrames com index ou colunas em comum para formar um novo DataFrame.
Mesclando DataFrames através de concatenações¶
Concatenar nada mais é do que “colar” dois ou mais DataFrames. Podemos concatenar por linhas ou por colunas.
A função que realiza a concatenação é concat
. Os dois argumentos mais utilizados são a lista de DataFrames a serem concatenados e axis
, onde axis = 0
indica concatenação por linha (um DataFrame “embaixo” do outro) e axis=1
indica concatenação por coluna (um DataFrame ao lado do outro).
Relembre do DataFrame df_dict_series
:
df_dict_series = pd.read_csv('../database/df_dict_series.csv')
Vamos criar um novo, com novas pessoas:
serie_Idade_nova = pd.Series({'Augusto':13, 'André': 17, 'Alexandre': 45}, name="Idade")
serie_Peso_novo = pd.Series({'Augusto':95, 'André': 65, 'Alexandre': 83}, name="Peso")
serie_Altura_nova = pd.Series({'Augusto':192, 'André': 175, 'Alexandre': 177}, name="Altura")
serie_sobrenome = pd.Series({'Augusto':'Castro', 'André':'Castro', 'Alexandre':'Castro'}, name='Sobrenome')
dicionario_novo = {'Sobrenome':serie_sobrenome, 'Peso': serie_Peso_novo,
'Idade': serie_Idade_nova, 'Altura': serie_Altura_nova}
df_novo = pd.DataFrame(dicionario_novo)
df_novo = df_novo.assign(IMC=round(df_novo.eval('Peso/(Altura/100)**2'),2))
df_novo
Sobrenome | Peso | Idade | Altura | IMC | |
---|---|---|---|---|---|
Augusto | Castro | 95 | 13 | 192 | 25.77 |
André | Castro | 65 | 17 | 175 | 21.22 |
Alexandre | Castro | 83 | 45 | 177 | 26.49 |
Agora vamos concatená-los:
pd.concat([df_dict_series,df_novo])
Unnamed: 0 | Idade | Peso | Altura | IMC | Sobrenome | |
---|---|---|---|---|---|---|
0 | Ana | 20 | 65 | 162 | 24.77 | Silva |
1 | João | 19 | 80 | 178 | 25.25 | PraDo |
2 | Maria | 21 | 62 | 162 | 23.62 | Sales |
3 | Pedro | 22 | 67 | 165 | 24.61 | MachadO |
4 | Túlio | 20 | 73 | 171 | 24.96 | Coutinho |
Augusto | NaN | 13 | 95 | 192 | 25.77 | Castro |
André | NaN | 17 | 65 | 175 | 21.22 | Castro |
Alexandre | NaN | 45 | 83 | 177 | 26.49 | Castro |
Concatenando por coluna¶
Para exemplificar vamos considerar os dados de COVID da Paraíba, selecionando casos novos e óbitos novos, e vamos obter dos dados do Brasil apenas os casos e óbitos diários do país, e vamos concatená-los por coluna.
covid_PB_casos_obitos = dados_covid_PB[['casosNovos','obitosNovos']]
Vamos tratar os dados do Brasil:
covid_BR_casos_obitos = covid_BR.query('regiao=="Brasil"')
covid_BR_casos_obitos = covid_BR_casos_obitos.set_index('data')
covid_BR_casos_obitos = covid_BR_casos_obitos[['casosNovos','obitosNovos']].rename({
'casosNovos':'casosBR', 'obitosNovos':'obitosBR'
}, axis=1)
covid_PB_casos_obitos
casosNovos | obitosNovos | |
---|---|---|
data | ||
2021-09-26 | 134 | 2.0 |
2021-09-25 | 165 | 2.0 |
2021-09-24 | 225 | 3.0 |
2021-09-23 | 203 | 3.0 |
2021-09-22 | 297 | 6.0 |
... | ... | ... |
2020-03-20 | 0 | 0.0 |
2020-03-19 | 0 | 0.0 |
2020-03-18 | 0 | 0.0 |
2020-03-17 | 0 | 0.0 |
2020-03-16 | 0 | 0.0 |
559 rows × 2 columns
covid_BR_casos_obitos
casosBR | obitosBR | |
---|---|---|
data | ||
2020-02-25 | 0 | 0 |
2020-02-26 | 1 | 0 |
2020-02-27 | 0 | 0 |
2020-02-28 | 0 | 0 |
2020-02-29 | 1 | 0 |
... | ... | ... |
2020-07-14 | 41857 | 1300 |
2020-07-15 | 39924 | 1233 |
2020-07-16 | 45403 | 1322 |
2020-07-17 | 34177 | 1163 |
2020-07-18 | 28532 | 921 |
145 rows × 2 columns
Vamos agora concatená-los por coluna:
pd.concat([covid_PB_casos_obitos, covid_BR_casos_obitos], axis=1)
casosNovos | obitosNovos | casosBR | obitosBR | |
---|---|---|---|---|
data | ||||
2021-09-26 | 134.0 | 2.0 | NaN | NaN |
2021-09-25 | 165.0 | 2.0 | NaN | NaN |
2021-09-24 | 225.0 | 3.0 | NaN | NaN |
2021-09-23 | 203.0 | 3.0 | NaN | NaN |
2021-09-22 | 297.0 | 6.0 | NaN | NaN |
... | ... | ... | ... | ... |
2020-03-11 | NaN | NaN | 18.0 | 0.0 |
2020-03-12 | NaN | NaN | 25.0 | 0.0 |
2020-03-13 | NaN | NaN | 21.0 | 0.0 |
2020-03-14 | NaN | NaN | 23.0 | 0.0 |
2020-03-15 | NaN | NaN | 79.0 | 0.0 |
579 rows × 4 columns
Para um polimento final, vamos substituir os valores NaN
que ocorreram antes do dia 13 de julho por 0. Para tanto, a forma ideal é utilizando o método map
:
dados_PB_BR = pd.concat([covid_PB_casos_obitos, covid_BR_casos_obitos], axis=1)
dados_PB_BR['casosNovos'] = dados_PB_BR.casosNovos.map(lambda caso: 0 if np.isnan(caso) else caso).astype('int')
dados_PB_BR['obitosNovos'] = dados_PB_BR.obitosNovos.map(lambda obito: 0 if np.isnan(obito) else obito).astype('int')
dados_PB_BR
casosNovos | obitosNovos | casosBR | obitosBR | |
---|---|---|---|---|
data | ||||
2021-09-26 | 134 | 2 | NaN | NaN |
2021-09-25 | 165 | 2 | NaN | NaN |
2021-09-24 | 225 | 3 | NaN | NaN |
2021-09-23 | 203 | 3 | NaN | NaN |
2021-09-22 | 297 | 6 | NaN | NaN |
... | ... | ... | ... | ... |
2020-03-11 | 0 | 0 | 18.0 | 0.0 |
2020-03-12 | 0 | 0 | 25.0 | 0.0 |
2020-03-13 | 0 | 0 | 21.0 | 0.0 |
2020-03-14 | 0 | 0 | 23.0 | 0.0 |
2020-03-15 | 0 | 0 | 79.0 | 0.0 |
579 rows × 4 columns
Mesclando DataFrames através de joins¶
Para realizar joins iremos utilizar a função merge
do pandas. joins tomam duas tabelas, uma tabela à esquerda e uma à direita e retornam uma terceira tabela contendo a união das colunas das duas tabelas.
Existem 4 tipos de joins:
left join: Apenas irão aparecer os index (da linha) que existem na tabela à esquerda;
right join: Apenas irão aparecer os index (da linha) que existem na tabela à direita;
inner join: Apenas irão aparecer os index que existem nas duas tabelas;
full join ou outer join: irão aparecer todos os index das duas tabelas.
Para exemplificar vamos considerar dois DataFrames (aqui teremos menos linhas, com nomes e dados fictícios). O primeiro DataFrame consistirá de nomes de alunos, CPF e matrícula da UFPB (nome_cpf_mat). O segundo DataFrame consistirá de nome, CPF e e-mail (nome_cpf_email). Nosso objetivo é criar um novo DataFrame contendo Nome, CPF, matrícula e e-mail.
Temos ainda as seguintes situações:
No DataFrame nome_cpf_mat existem alunos que não estão presentes no nome_cpf_email, pois não enviaram esta informação.
No DataFrame nome_cpf_email existem alunos que não estão presentes no nome_cpf_mat pois estes não são alunos da UFPB.
nome_cpf_mat = pd.read_csv('../database/nome_cpf_mat.csv')
nome_cpf_email = pd.read_csv('../database/nome_cpf_email.csv')
Vamos agora examinar os DataFrames. Como são bem simples, basta realizar prints deles.
nome_cpf_mat
Nome | CPF | Matricula | |
---|---|---|---|
0 | João Paulo | 326.475.190-99 | 8848484 |
1 | Ana Silva | 073.101.240-22 | 8451212 |
2 | Antonio Carlos | 830.060.930-03 | 5151213 |
3 | Debora Santos | 472.006.460-40 | 51848484 |
4 | Rodrigo Gomes | 566.712.550-16 | 1415816 |
5 | Edson Jardim | 308.226.400-07 | 9592303 |
nome_cpf_email
Nome | CPF | ||
---|---|---|---|
0 | João Paulo | 326.475.190-99 | joao@inventado.com.br |
1 | Ana Silva | 073.101.240-22 | ana@inventado.com.br |
2 | Antonio Carlos | 830.060.930-03 | antonio@inventado.com.br |
3 | Saulo Santos | 370.981.810-99 | saulo@inventado.com.br |
4 | Paulo Cardoso | 250.078.710-95 | paulo@inventado.com.br |
5 | Edson Jardim | 308.226.400-07 | edson@inventado.com.br |
6 | Ana Silva | 344.246.630-00 | anasilva@inventado.com.br |
Tipicamente é bom possuir index únicos. Neste sentido, vamos definir o CPF como index:
nome_cpf_mat = nome_cpf_mat.set_index('CPF')
nome_cpf_email = nome_cpf_email.set_index('CPF')
Vamos agora realizar um left join com o DataFrame nome_cpf_mat ficando à esquerda (neste caso, apenas alunos com matrícula irão aparecer):
pd.merge(nome_cpf_mat, nome_cpf_email, how = 'left', on = ['Nome','CPF'])
Nome | Matricula | ||
---|---|---|---|
CPF | |||
326.475.190-99 | João Paulo | 8848484 | joao@inventado.com.br |
073.101.240-22 | Ana Silva | 8451212 | ana@inventado.com.br |
830.060.930-03 | Antonio Carlos | 5151213 | antonio@inventado.com.br |
472.006.460-40 | Debora Santos | 51848484 | NaN |
566.712.550-16 | Rodrigo Gomes | 1415816 | NaN |
308.226.400-07 | Edson Jardim | 9592303 | edson@inventado.com.br |
Na opção how dizemos qual o tipo de join que queremos realizar.
Na opção on dizemos quais as colunas que existem em comum nos DataFrames.
Veja o que aconteceria se informássemos apenas que o CPF está presente nos dois DataFrames:
pd.merge(nome_cpf_mat, nome_cpf_email, how = 'left', on = 'CPF')
Nome_x | Matricula | Nome_y | ||
---|---|---|---|---|
CPF | ||||
326.475.190-99 | João Paulo | 8848484 | João Paulo | joao@inventado.com.br |
073.101.240-22 | Ana Silva | 8451212 | Ana Silva | ana@inventado.com.br |
830.060.930-03 | Antonio Carlos | 5151213 | Antonio Carlos | antonio@inventado.com.br |
472.006.460-40 | Debora Santos | 51848484 | NaN | NaN |
566.712.550-16 | Rodrigo Gomes | 1415816 | NaN | NaN |
308.226.400-07 | Edson Jardim | 9592303 | Edson Jardim | edson@inventado.com.br |
Observe que os nomes dos alunos que estão na segunda tabela ficam indeterminados na coluna Nome_y.
Vamos agora realizar um right join com o DataFrame nome_cpf_mat ficando à esquerda (neste caso, apenas alunos com e-mail irão aparecer):
pd.merge(nome_cpf_mat, nome_cpf_email, how = 'right', on = ['Nome','CPF'])
Nome | Matricula | ||
---|---|---|---|
CPF | |||
326.475.190-99 | João Paulo | 8848484.0 | joao@inventado.com.br |
073.101.240-22 | Ana Silva | 8451212.0 | ana@inventado.com.br |
830.060.930-03 | Antonio Carlos | 5151213.0 | antonio@inventado.com.br |
370.981.810-99 | Saulo Santos | NaN | saulo@inventado.com.br |
250.078.710-95 | Paulo Cardoso | NaN | paulo@inventado.com.br |
308.226.400-07 | Edson Jardim | 9592303.0 | edson@inventado.com.br |
344.246.630-00 | Ana Silva | NaN | anasilva@inventado.com.br |
Vamos agora realizar um inner join com o DataFrame nome_cpf_mat ficando à esquerda (neste caso, apenas alunos com matrícula e com e-mail irão aparecer):
pd.merge(nome_cpf_mat, nome_cpf_email, how = 'inner', on = ['Nome','CPF'])
Nome | Matricula | ||
---|---|---|---|
CPF | |||
326.475.190-99 | João Paulo | 8848484 | joao@inventado.com.br |
073.101.240-22 | Ana Silva | 8451212 | ana@inventado.com.br |
830.060.930-03 | Antonio Carlos | 5151213 | antonio@inventado.com.br |
308.226.400-07 | Edson Jardim | 9592303 | edson@inventado.com.br |
Por fim, vamos agora realizar um outer ou full join com o DataFrame nome_cpf_mat ficando à esquerda (neste caso, todos os alunos irão aparecer):
pd.merge(nome_cpf_mat, nome_cpf_email, how = 'outer', on = ['Nome','CPF'])
Nome | Matricula | ||
---|---|---|---|
CPF | |||
326.475.190-99 | João Paulo | 8848484.0 | joao@inventado.com.br |
073.101.240-22 | Ana Silva | 8451212.0 | ana@inventado.com.br |
830.060.930-03 | Antonio Carlos | 5151213.0 | antonio@inventado.com.br |
472.006.460-40 | Debora Santos | 51848484.0 | NaN |
566.712.550-16 | Rodrigo Gomes | 1415816.0 | NaN |
308.226.400-07 | Edson Jardim | 9592303.0 | edson@inventado.com.br |
370.981.810-99 | Saulo Santos | NaN | saulo@inventado.com.br |
250.078.710-95 | Paulo Cardoso | NaN | paulo@inventado.com.br |
344.246.630-00 | Ana Silva | NaN | anasilva@inventado.com.br |
Os métodos apply, map e applymap¶
A ideia é relativamente simples. Os três métodos são vetorizados e aplicam uma função ou uma substituição via dicionário de tal forma que:
apply é realizado via linha ou coluna em um DataFrame;
map é aplicado a cada elemento de uma Series;
applymap é aplicado a cada elemento de um DataFrame.
Já vimos diversos exemplos de uso de map
. Vejamos exemplos de applymap
e apply
.
Neste exemplo vamos retomar a concatenação entre os dados da Paraíba e do Brasil, porém iremos substituir todos os valores de
NaN
por zero, usando o métodpapplymap
.
dados_PB_BR = pd.concat([covid_PB_casos_obitos, covid_BR_casos_obitos], axis=1)
dados_PB_BR.applymap(lambda valor: 0 if np.isnan(valor) else valor)
casosNovos | obitosNovos | casosBR | obitosBR | |
---|---|---|---|---|
data | ||||
2021-09-26 | 134.0 | 2.0 | 0.0 | 0.0 |
2021-09-25 | 165.0 | 2.0 | 0.0 | 0.0 |
2021-09-24 | 225.0 | 3.0 | 0.0 | 0.0 |
2021-09-23 | 203.0 | 3.0 | 0.0 | 0.0 |
2021-09-22 | 297.0 | 6.0 | 0.0 | 0.0 |
... | ... | ... | ... | ... |
2020-03-11 | 0.0 | 0.0 | 18.0 | 0.0 |
2020-03-12 | 0.0 | 0.0 | 25.0 | 0.0 |
2020-03-13 | 0.0 | 0.0 | 21.0 | 0.0 |
2020-03-14 | 0.0 | 0.0 | 23.0 | 0.0 |
2020-03-15 | 0.0 | 0.0 | 79.0 | 0.0 |
579 rows × 4 columns
Vamos utilizar apply
para realizar a soma de casos e óbitos através de mais de uma forma
dados_PB_BR.apply(lambda x: np.sum(x)).astype('int')
casosNovos 440037
obitosNovos 9294
casosBR 2074860
obitosBR 78772
dtype: int64
Se quisermos realizar a operação por linhas, basta utilizar o argumento axis=1
:
dados_PB_BR.apply(lambda x: (x>0).all(), axis=1)
data
2021-09-26 False
2021-09-25 False
2021-09-24 False
2021-09-23 False
2021-09-22 False
...
2020-03-11 False
2020-03-12 False
2020-03-13 False
2020-03-14 False
2020-03-15 False
Length: 579, dtype: bool