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     199706
obitosNovos      4171
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-02-09 199706 971 237369 152779 4171 13 0.0209
2021-02-08 198735 611 237189 151879 4158 12 0.0209
2021-02-07 198124 664 237072 151535 4146 11 0.0209
2021-02-06 197460 918 236774 150175 4135 12 0.0209
2021-02-05 196542 1060 236216 150169 4123 13 0.0210

Isto também pode ser obtido utilizando o método sum de DataFrames e Series:

dados_covid_PB[['casosNovos','obitosNovos']].sum()
casosNovos     199706
obitosNovos      4171
dtype: int64

Podemos recriar a coluna 'obitosAcumulados' com o método cumsum (soma cumulativa):

dados_covid_PB.obitosNovos.sort_index().cumsum()
data
2020-03-16       0
2020-03-17       0
2020-03-18       0
2020-03-19       0
2020-03-20       0
              ... 
2021-02-05    4123
2021-02-06    4135
2021-02-07    4146
2021-02-08    4158
2021-02-09    4171
Name: obitosNovos, Length: 331, dtype: int64

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('data/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_BRe 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('data/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-02-09 971 13
2021-02-08 611 12
2021-02-07 664 11
2021-02-06 918 12
2021-02-05 1060 13
... ... ...
2020-03-20 0 0
2020-03-19 0 0
2020-03-18 0 0
2020-03-17 0 0
2020-03-16 0 0

331 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
2021-02-09 971.0 13.0 NaN NaN
2021-02-08 611.0 12.0 NaN NaN
2021-02-07 664.0 11.0 NaN NaN
2021-02-06 918.0 12.0 NaN NaN
2021-02-05 1060.0 13.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

351 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
2021-02-09 971 13 NaN NaN
2021-02-08 611 12 NaN NaN
2021-02-07 664 11 NaN NaN
2021-02-06 918 12 NaN NaN
2021-02-05 1060 13 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

351 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('data/nome_cpf_mat.csv')
nome_cpf_email = pd.read_csv('data/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 e-mail
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 e-mail
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 e-mail
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 e-mail
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
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

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 e-mail
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 e-mail
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étodp applymap.

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
2021-02-09 971.0 13.0 0.0 0.0
2021-02-08 611.0 12.0 0.0 0.0
2021-02-07 664.0 11.0 0.0 0.0
2021-02-06 918.0 12.0 0.0 0.0
2021-02-05 1060.0 13.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

351 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      199706
obitosNovos       4171
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)
2021-02-09    False
2021-02-08    False
2021-02-07    False
2021-02-06    False
2021-02-05    False
              ...  
2020-03-11    False
2020-03-12    False
2020-03-13    False
2020-03-14    False
2020-03-15    False
Length: 351, dtype: bool