Manipulação de dados - II¶
DataFrames¶
Como dissemos anterioremente, o DataFrame é a segunda estrutura basilar do pandas. Um DataFrame:
é uma tabela, ou seja, é bidimensional;
tem cada coluna formada como uma Series do pandas;
pode ter Series contendo tipos de dado diferentes.
import numpy as np
import pandas as pd
Criação de um DataFrame¶
O método padrão para criarmos um DataFrame é através de uma função com mesmo nome.
df_exemplo = pd.DataFrame(dados_de_interesse, index = indice_de_interesse,
columns = colunas_de_interesse)
Ao criar um DataFrame, podemos informar
index
: rótulos para as linhas (atributos index das Series).columns
: rótulos para as colunas (atributos name das Series).
No template, dados_de_interesse
pode ser
um dicionário de:
arrays unidimensionais do numpy;
listas;
dicionários;
Series do pandas.
um array bidimensional do numpy;
uma Series do Pandas;
outro DataFrame.
DataFrame a partir de dicionários de Series¶
Neste método de criação, as Series do dicionário não precisam possuir o mesmo número de elementos. O index do DataFrame será dado pela união dos index de todas as Series contidas no dicionário.
Exemplo:
serie_Idade = pd.Series({'Ana':20, 'João': 19, 'Maria': 21, 'Pedro': 22}, name="Idade")
serie_Peso = pd.Series({'Ana':55, 'João': 80, 'Maria': 62, 'Pedro': 67, 'Túlio': 73}, name="Peso")
serie_Altura = pd.Series({'Ana':162, 'João': 178, 'Maria': 162, 'Pedro': 165, 'Túlio': 171}, name="Altura")
dicionario_series_exemplo = {'Idade': serie_Idade, 'Peso': serie_Peso, 'Altura': serie_Altura}
df_dict_series = pd.DataFrame(dicionario_series_exemplo)
df_dict_series
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20.0 | 55 | 162 |
João | 19.0 | 80 | 178 |
Maria | 21.0 | 62 | 162 |
Pedro | 22.0 | 67 | 165 |
Túlio | NaN | 73 | 171 |
Compare este resultado com a criação de uma planilha pelos métodos usuais. Veja que há muita flexibilidade para criarmos ou modificarmos uma tabela.
Vejamos exemplos sobre como acessar intervalos de dados na tabela.
pd.DataFrame(dicionario_series_exemplo, index=['Ana','Maria'])
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
Maria | 21 | 62 | 162 |
pd.DataFrame(dicionario_series_exemplo, index=['Ana','Maria'], columns=['Peso','Altura'])
Peso | Altura | |
---|---|---|
Ana | 55 | 162 |
Maria | 62 | 162 |
Neste exemplo, adicionamos a coluna IMC
, ainda sem valores calculados.
pd.DataFrame(dicionario_series_exemplo, index=['Ana','Maria','Paula'],
columns=['Peso','Altura','IMC'])
Peso | Altura | IMC | |
---|---|---|---|
Ana | 55.0 | 162.0 | NaN |
Maria | 62.0 | 162.0 | NaN |
Paula | NaN | NaN | NaN |
df_exemplo_IMC = pd.DataFrame(dicionario_series_exemplo,
columns=['Peso','Altura','IMC'])
Agora, mostramos como os valores do IMC podem ser calculados diretamente por computação vetorizada sobre as Series.
df_exemplo_IMC['IMC']=round(df_exemplo_IMC['Peso']/(df_exemplo_IMC['Altura']/100)**2,2)
df_exemplo_IMC
Peso | Altura | IMC | |
---|---|---|---|
Ana | 55 | 162 | 20.96 |
João | 80 | 178 | 25.25 |
Maria | 62 | 162 | 23.62 |
Pedro | 67 | 165 | 24.61 |
Túlio | 73 | 171 | 24.96 |
DataFrame a partir de dicionários de listas ou arrays do numpy¶
Neste método de criação, os arrays ou as listas devem possuir o mesmo comprimento. Se o index não for informado, o index será dado de forma similar ao do objeto tipo Series.
Exemplo com dicionário de listas:
dicionario_lista_exemplo = {'Idade': [20,19,21,22,20],
'Peso': [55,80,62,67,73],
'Altura': [162,178,162,165,171]}
pd.DataFrame(dicionario_lista_exemplo)
Idade | Peso | Altura | |
---|---|---|---|
0 | 20 | 55 | 162 |
1 | 19 | 80 | 178 |
2 | 21 | 62 | 162 |
3 | 22 | 67 | 165 |
4 | 20 | 73 | 171 |
Mais exemplos:
pd.DataFrame(dicionario_lista_exemplo, index=['Ana','João','Maria','Pedro','Túlio'])
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
Exemplos com dicionário de arrays do numpy:
dicionario_array_exemplo = {'Idade': np.array([20,19,21,22,20]),
'Peso': np.array([55,80,62,67,73]),
'Altura': np.array([162,178,162,165,171])}
pd.DataFrame(dicionario_array_exemplo)
Idade | Peso | Altura | |
---|---|---|---|
0 | 20 | 55 | 162 |
1 | 19 | 80 | 178 |
2 | 21 | 62 | 162 |
3 | 22 | 67 | 165 |
4 | 20 | 73 | 171 |
Mais exemplos:
pd.DataFrame(dicionario_array_exemplo, index=['Ana','João','Maria','Pedro','Túlio'])
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
DataFrame a partir de uma Series do pandas¶
Neste caso, o DataFrame terá o mesmo index que a Series do pandas e apenas uma coluna.
series_exemplo = pd.Series({'Ana':20, 'João': 19, 'Maria': 21, 'Pedro': 22, 'Túlio': 20})
pd.DataFrame(series_exemplo)
0 | |
---|---|
Ana | 20 |
João | 19 |
Maria | 21 |
Pedro | 22 |
Túlio | 20 |
Caso a Series possua um atributo name
especificado, este será o nome da coluna do DataFrame.
series_exemplo_Idade = pd.Series({'Ana':20, 'João': 19, 'Maria': 21, 'Pedro': 22, 'Túlio': 20}, name="Idade")
pd.DataFrame(series_exemplo_Idade)
Idade | |
---|---|
Ana | 20 |
João | 19 |
Maria | 21 |
Pedro | 22 |
Túlio | 20 |
DataFrame a partir de lista de Series do pandas¶
Neste caso, a entrada dos dados da lista no DataFrame será feita por linha.
pd.DataFrame([serie_Peso, serie_Altura, serie_Idade])
Ana | João | Maria | Pedro | Túlio | |
---|---|---|---|---|---|
Peso | 55.0 | 80.0 | 62.0 | 67.0 | 73.0 |
Altura | 162.0 | 178.0 | 162.0 | 165.0 | 171.0 |
Idade | 20.0 | 19.0 | 21.0 | 22.0 | NaN |
Podemos corrigir a orientação usando o método transpose
.
pd.DataFrame([serie_Peso, serie_Altura, serie_Idade]).transpose()
Peso | Altura | Idade | |
---|---|---|---|
Ana | 55.0 | 162.0 | 20.0 |
João | 80.0 | 178.0 | 19.0 |
Maria | 62.0 | 162.0 | 21.0 |
Pedro | 67.0 | 165.0 | 22.0 |
Túlio | 73.0 | 171.0 | NaN |
DataFrame a partir de arquivos¶
Para criar um DataFrame a partir de um arquivo, precisamos de funções do tipo pd.read_FORMATO
, onde FORMATO
indica o formato a ser importado sob o pressuposto de que a biblioteca pandas foi devidamente importada com pd
.
Os formatos mais comuns são:
csv (comma-separated values),
xls ou xlsx (formatos do Microsoft Excel),
hdf5 (comumente utilizado em big data),
json (comumente utilizado em páginas da internet).
As funções para leitura correspondentes são:
pd.read_csv
,pd.read_excel
,pd.read_hdf
,pd.read_json
,
respectivamente.
De todas elas, a função mais utilizada é read_csv
. Ela possui vários argumentos. Vejamos os mais utilizados:
file_path_or_buffer
: o endereço do arquivo a ser lido. Pode ser um endereço da internet.sep
: o separador entre as entradas de dados. O separador padrão é,
.index_col
: a coluna que deve ser usada para formar o index. O padrão éNone
. Porém pode ser alterado para outro. Um separador comumente encontrado é o\t
(TAB).names
: nomes das colunas a serem usadas. O padrão éNone
.header
: número da linha que servirá como nome para as colunas. O padrão éinfer
(ou seja, tenta deduzir automaticamente). Se os nomes das colunas forem passados através donames
, entãoheader
será automaticamente considerado comoNone
.
Exemplo: considere o arquivo data/exemplo_data.csv
contendo:
,coluna_1,coluna_2
2020-01-01,-0.4160923582996922,1.8103644347460834
2020-01-02,-0.1379696602473578,2.5785204825192785
2020-01-03,0.5758273450544708,0.06086648807755068
2020-01-04,-0.017367186564883633,1.2995865328684455
2020-01-05,1.3842792448510655,-0.3817320973859929
2020-01-06,0.5497056238566345,-1.308789022968975
2020-01-07,-0.2822962331437976,-1.6889791765925102
2020-01-08,-0.9897300598660013,-0.028120707936426497
2020-01-09,0.27558240737928663,-0.1776585993494299
2020-01-10,0.6851316082235455,0.5025348904591399
Para ler o arquivo acima basta fazer:
df_exemplo_0 = pd.read_csv('../database/exemplo_data.csv')
df_exemplo_0
Unnamed: 0 | coluna_1 | coluna_2 | |
---|---|---|---|
0 | 2020-01-01 | -0.416092 | 1.810364 |
1 | 2020-01-02 | -0.137970 | 2.578520 |
2 | 2020-01-03 | 0.575827 | 0.060866 |
3 | 2020-01-04 | -0.017367 | 1.299587 |
4 | 2020-01-05 | 1.384279 | -0.381732 |
5 | 2020-01-06 | 0.549706 | -1.308789 |
6 | 2020-01-07 | -0.282296 | -1.688979 |
7 | 2020-01-08 | -0.989730 | -0.028121 |
8 | 2020-01-09 | 0.275582 | -0.177659 |
9 | 2020-01-10 | 0.685132 | 0.502535 |
No exemplo anterior, as colunas receberam nomes corretamentes exceto pela primeira coluna que gostaríamos de considerar como index. Neste caso fazemos:
df_exemplo = pd.read_csv('../database/exemplo_data.csv', index_col=0)
df_exemplo
coluna_1 | coluna_2 | |
---|---|---|
2020-01-01 | -0.416092 | 1.810364 |
2020-01-02 | -0.137970 | 2.578520 |
2020-01-03 | 0.575827 | 0.060866 |
2020-01-04 | -0.017367 | 1.299587 |
2020-01-05 | 1.384279 | -0.381732 |
2020-01-06 | 0.549706 | -1.308789 |
2020-01-07 | -0.282296 | -1.688979 |
2020-01-08 | -0.989730 | -0.028121 |
2020-01-09 | 0.275582 | -0.177659 |
2020-01-10 | 0.685132 | 0.502535 |
O método head do DataFrame¶
O método head
, sem argumento, permite que visualizemos as 5 primeiras linhas do DataFrame.
df_exemplo.head()
coluna_1 | coluna_2 | |
---|---|---|
2020-01-01 | -0.416092 | 1.810364 |
2020-01-02 | -0.137970 | 2.578520 |
2020-01-03 | 0.575827 | 0.060866 |
2020-01-04 | -0.017367 | 1.299587 |
2020-01-05 | 1.384279 | -0.381732 |
Se for passado um argumento com valor n
, as n
primeiras linhas são impressas.
df_exemplo.head(2)
coluna_1 | coluna_2 | |
---|---|---|
2020-01-01 | -0.416092 | 1.810364 |
2020-01-02 | -0.137970 | 2.578520 |
df_exemplo.head(7)
coluna_1 | coluna_2 | |
---|---|---|
2020-01-01 | -0.416092 | 1.810364 |
2020-01-02 | -0.137970 | 2.578520 |
2020-01-03 | 0.575827 | 0.060866 |
2020-01-04 | -0.017367 | 1.299587 |
2020-01-05 | 1.384279 | -0.381732 |
2020-01-06 | 0.549706 | -1.308789 |
2020-01-07 | -0.282296 | -1.688979 |
O método tail
do DataFrame¶
O método tail
, sem argumento, retorna as últimas 5 linhas do DataFrame.
df_exemplo.tail()
coluna_1 | coluna_2 | |
---|---|---|
2020-01-06 | 0.549706 | -1.308789 |
2020-01-07 | -0.282296 | -1.688979 |
2020-01-08 | -0.989730 | -0.028121 |
2020-01-09 | 0.275582 | -0.177659 |
2020-01-10 | 0.685132 | 0.502535 |
Se for passado um argumento com valor n
, as n
últimas linhas são impressas.
df_exemplo.tail(2)
coluna_1 | coluna_2 | |
---|---|---|
2020-01-09 | 0.275582 | -0.177659 |
2020-01-10 | 0.685132 | 0.502535 |
df_exemplo.tail(7)
coluna_1 | coluna_2 | |
---|---|---|
2020-01-04 | -0.017367 | 1.299587 |
2020-01-05 | 1.384279 | -0.381732 |
2020-01-06 | 0.549706 | -1.308789 |
2020-01-07 | -0.282296 | -1.688979 |
2020-01-08 | -0.989730 | -0.028121 |
2020-01-09 | 0.275582 | -0.177659 |
2020-01-10 | 0.685132 | 0.502535 |
Atributos de Series e DataFrames¶
Atributos comumente usados para Series e DataFrames são:
shape
: fornece as dimensões do objeto em questão (Series ou DataFrame) em formato consistente com o atributoshape
de um array do numpy.index
: fornece o índice do objeto. No caso do DataFrame são os rótulos das linhas.columns
: fornece as colunas (apenas disponível para DataFrames)
Exemplo:
df_exemplo.shape
(10, 2)
serie_1 = pd.Series([1,2,3,4,5])
serie_1.shape
(5,)
df_exemplo.index
Index(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05',
'2020-01-06', '2020-01-07', '2020-01-08', '2020-01-09', '2020-01-10'],
dtype='object')
serie_1.index
RangeIndex(start=0, stop=5, step=1)
df_exemplo.columns
Index(['coluna_1', 'coluna_2'], dtype='object')
Se quisermos obter os dados contidos nos index ou nas Series podemos utilizar a propriedade .array
.
serie_1.index.array
<PandasArray>
[0, 1, 2, 3, 4]
Length: 5, dtype: int64
df_exemplo.columns.array
<PandasArray>
['coluna_1', 'coluna_2']
Length: 2, dtype: object
Se o interesse for obter os dados como um array
do numpy, devemos utilizar o método .to_numpy()
.
Exemplo:
serie_1.index.to_numpy()
array([0, 1, 2, 3, 4])
df_exemplo.columns.to_numpy()
array(['coluna_1', 'coluna_2'], dtype=object)
O método .to_numpy()
também está disponível em DataFrames:
df_exemplo.to_numpy()
array([[-0.41609236, 1.81036443],
[-0.13796966, 2.57852048],
[ 0.57582735, 0.06086649],
[-0.01736719, 1.29958653],
[ 1.38427924, -0.3817321 ],
[ 0.54970562, -1.30878902],
[-0.28229623, -1.68897918],
[-0.98973006, -0.02812071],
[ 0.27558241, -0.1776586 ],
[ 0.68513161, 0.50253489]])
A função do numpy asarray()
é compatível com index, columns e DataFrames do pandas:
np.asarray(df_exemplo.index)
array(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',
'2020-01-05', '2020-01-06', '2020-01-07', '2020-01-08',
'2020-01-09', '2020-01-10'], dtype=object)
np.asarray(df_exemplo.columns)
array(['coluna_1', 'coluna_2'], dtype=object)
np.asarray(df_exemplo)
array([[-0.41609236, 1.81036443],
[-0.13796966, 2.57852048],
[ 0.57582735, 0.06086649],
[-0.01736719, 1.29958653],
[ 1.38427924, -0.3817321 ],
[ 0.54970562, -1.30878902],
[-0.28229623, -1.68897918],
[-0.98973006, -0.02812071],
[ 0.27558241, -0.1776586 ],
[ 0.68513161, 0.50253489]])
Informações sobre as colunas de um DataFrame¶
Para obtermos uma breve descrição sobre as colunas de um DataFrame utilizamos o método info
.
Exemplo:
df_exemplo.info()
<class 'pandas.core.frame.DataFrame'>
Index: 10 entries, 2020-01-01 to 2020-01-10
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 coluna_1 10 non-null float64
1 coluna_2 10 non-null float64
dtypes: float64(2)
memory usage: 240.0+ bytes
Criando arquivos a partir de DataFrames¶
Para criar arquivos a partir de DataFrames, basta utilizar os métodos do tipo pd.to_FORMATO
, onde FORMATO
indica o formato a ser exportado e supondo que a biblioteca pandas foi importada com pd
.
Com relação aos tipos de arquivo anteriores, os métodos para exportação correspondentes são:
.to_csv
(‘endereço_do_arquivo’),.to_excel
(‘endereço_do_arquivo’),.to_hdf
(‘endereço_do_arquivo’),.to_json
(‘endereço_do_arquivo’),
onde endereço_do_arquivo
é uma str
que contém o endereço do arquivo a ser exportado.
Exemplo:
Para exportar para o arquivo exemplo_novo.csv
, utilizaremos o método .to_csv
ao DataFrame df_exemplo
:
df_exemplo.to_csv('../database/exemplo_novo.csv')
Exemplo COVID-19 PB¶
Dados diários de COVID-19 do estado da Paraíba:
Fonte: https://superset.plataformatarget.com.br/superset/dashboard/microdados/
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.info()
<class 'pandas.core.frame.DataFrame'>
Index: 559 entries, 2021-09-26 to 2020-03-16
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 casosAcumulados 559 non-null int64
1 casosNovos 559 non-null int64
2 descartados 559 non-null int64
3 recuperados 559 non-null int64
4 obitosAcumulados 559 non-null int64
5 obitosNovos 558 non-null float64
6 Letalidade 559 non-null float64
dtypes: float64(2), int64(5)
memory usage: 34.9+ KB
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 |
dados_covid_PB.tail()
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2020-03-20 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 |
2020-03-19 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 |
2020-03-18 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 |
2020-03-17 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 |
2020-03-16 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 |
dados_covid_PB['estado'] = 'PB'
dados_covid_PB.head()
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | estado | |
---|---|---|---|---|---|---|---|---|
data | ||||||||
2021-09-26 | 441155 | 134 | 484336 | 333751 | 9294 | 2.0 | 0.0211 | PB |
2021-09-25 | 441021 | 165 | 484331 | 333441 | 9292 | 2.0 | 0.0211 | PB |
2021-09-24 | 440856 | 225 | 484301 | 332845 | 9290 | 3.0 | 0.0211 | PB |
2021-09-23 | 440631 | 203 | 484276 | 332540 | 9287 | 3.0 | 0.0211 | PB |
2021-09-22 | 440428 | 297 | 484265 | 331958 | 9284 | 6.0 | 0.0211 | PB |
dados_covid_PB.to_csv('../database/dadoscovidpb.csv')
Índices dos valores máximos ou mínimos¶
Os métodos idxmin()
e idxmax()
retornam o index cuja entrada fornece o valor mínimo ou máximo da Series ou DataFrame. Se houver múltiplas ocorrências de mínimos ou máximos, o método retorna a primeira ocorrência.
Vamos recriar um DataFrame genérico.
serie_Idade = pd.Series({'Ana':20, 'João': 19, 'Maria': 21, 'Pedro': 22, 'Túlio': 20}, name="Idade")
serie_Peso = pd.Series({'Ana':55, 'João': 80, 'Maria': 62, 'Pedro': 67, 'Túlio': 73}, name="Peso")
serie_Altura = pd.Series({'Ana':162, 'João': 178, 'Maria': 162, 'Pedro': 165, 'Túlio': 171}, name="Altura")
dicionario_series_exemplo = {'Idade': serie_Idade, 'Peso': serie_Peso, 'Altura': serie_Altura}
df_dict_series = pd.DataFrame(dicionario_series_exemplo)
df_dict_series
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
Assim, podemos localizar quem possui menores idade, peso e altura.
df_dict_series.idxmin()
Idade João
Peso Ana
Altura Ana
dtype: object
De igual forma, localizamos quem possui maiores idade, peso e altura.
df_dict_series.idxmax()
Idade Pedro
Peso João
Altura João
dtype: object
Exemplo: Aplicaremos as funções idxmin()
e idxmax()
aos dados do arquivo data/exemplo_data.csv
para localizar entradas de interesse.
df_exemplo = pd.read_csv('../database/exemplo_data.csv', index_col=0); df_exemplo
coluna_1 | coluna_2 | |
---|---|---|
2020-01-01 | -0.416092 | 1.810364 |
2020-01-02 | -0.137970 | 2.578520 |
2020-01-03 | 0.575827 | 0.060866 |
2020-01-04 | -0.017367 | 1.299587 |
2020-01-05 | 1.384279 | -0.381732 |
2020-01-06 | 0.549706 | -1.308789 |
2020-01-07 | -0.282296 | -1.688979 |
2020-01-08 | -0.989730 | -0.028121 |
2020-01-09 | 0.275582 | -0.177659 |
2020-01-10 | 0.685132 | 0.502535 |
df_exemplo = pd.DataFrame(df_exemplo, columns=['coluna_1','coluna_2','coluna_3'])
Inserimos uma terceira coluna com dados fictícios.
df_exemplo['coluna_3'] = pd.Series([1,2,3,4,5,6,7,8,np.nan,np.nan],index=df_exemplo.index)
df_exemplo
coluna_1 | coluna_2 | coluna_3 | |
---|---|---|---|
2020-01-01 | -0.416092 | 1.810364 | 1.0 |
2020-01-02 | -0.137970 | 2.578520 | 2.0 |
2020-01-03 | 0.575827 | 0.060866 | 3.0 |
2020-01-04 | -0.017367 | 1.299587 | 4.0 |
2020-01-05 | 1.384279 | -0.381732 | 5.0 |
2020-01-06 | 0.549706 | -1.308789 | 6.0 |
2020-01-07 | -0.282296 | -1.688979 | 7.0 |
2020-01-08 | -0.989730 | -0.028121 | 8.0 |
2020-01-09 | 0.275582 | -0.177659 | NaN |
2020-01-10 | 0.685132 | 0.502535 | NaN |
Os index correspondentes aos menores e maiores valores são datas, evidentemente.
df_exemplo.idxmin()
coluna_1 2020-01-08
coluna_2 2020-01-07
coluna_3 2020-01-01
dtype: object
df_exemplo.idxmax()
coluna_1 2020-01-05
coluna_2 2020-01-02
coluna_3 2020-01-08
dtype: object
Reindexação de DataFrames¶
No pandas, o método reindex
reordena o DataFrame de acordo com o conjunto de rótulos inserido como argumento;
insere valores faltantes caso um rótulo do novo index não tenha valor atribuído no conjunto de dados;
remove valores correspondentes a rótulos que não estão presentes no novo index.
Exemplos:
df_dict_series.reindex(index=['Victor', 'Túlio', 'Pedro', 'João'], columns=['Altura','Peso','IMC'])
Altura | Peso | IMC | |
---|---|---|---|
Victor | NaN | NaN | NaN |
Túlio | 171.0 | 73.0 | NaN |
Pedro | 165.0 | 67.0 | NaN |
João | 178.0 | 80.0 | NaN |
Remoção de linhas ou colunas de um DataFrame¶
Para remover linhas ou colunas de um DataFrame do pandas podemos utilizar o método drop
. O argumento axis
identifica o eixo de remoção: axis=0
, que é o padrão, indica a remoção de uma ou mais linhas; axis=1
indica a remoção de uma ou mais colunas.
Nos exemplos que segue, note que novos DataFrames são obtidos a partir de df_dict_series
sem que este seja sobrescrito.
df_dict_series.drop('Túlio') # axis=0 implícito
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
df_dict_series.drop(['Ana','Maria'], axis=0)
Idade | Peso | Altura | |
---|---|---|---|
João | 19 | 80 | 178 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
df_dict_series.drop(['Idade'], axis=1)
Peso | Altura | |
---|---|---|
Ana | 55 | 162 |
João | 80 | 178 |
Maria | 62 | 162 |
Pedro | 67 | 165 |
Túlio | 73 | 171 |
Renomeando index e columns¶
O método rename
retorna uma cópia na qual o index (no caso de Series e DataFrames) e columns (no caso de DataFrames) foram renomeados. O método aceita como entrada um dicionário, uma Series do pandas ou uma função.
Exemplo:
serie_exemplo = pd.Series([1,2,3], index=['a','b','c'])
serie_exemplo
a 1
b 2
c 3
dtype: int64
serie_exemplo.rename({'a':'abacaxi', 'b':'banana', 'c': 'cebola'})
abacaxi 1
banana 2
cebola 3
dtype: int64
Exemplo:
df_dict_series
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
df_dict_series.rename(index = {'Ana':'a', 'João':'j', 'Maria':'m', 'Pedro':'p','Túlio':'t'},
columns = {'Idade':'I', 'Peso':'P','Altura':'A'})
I | P | A | |
---|---|---|---|
a | 20 | 55 | 162 |
j | 19 | 80 | 178 |
m | 21 | 62 | 162 |
p | 22 | 67 | 165 |
t | 20 | 73 | 171 |
No próximo exemplo, usamos uma Series para renomear os rótulos.
indice_novo = pd.Series({'Ana':'a', 'João':'j', 'Maria':'m', 'Pedro':'p','Túlio':'t'})
df_dict_series.rename(index = indice_novo)
Idade | Peso | Altura | |
---|---|---|---|
a | 20 | 55 | 162 |
j | 19 | 80 | 178 |
m | 21 | 62 | 162 |
p | 22 | 67 | 165 |
t | 20 | 73 | 171 |
Neste exemplo, usamos a função str.upper
(altera a str
para “todas maiúsculas”) para renomear colunas.
df_dict_series.rename(columns=str.upper)
IDADE | PESO | ALTURA | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
Ordenação de Series e DataFrames¶
É possível ordenar ambos pelos rótulos do index (para tanto é necessário que eles sejam ordenáveis) ou por valores nas colunas.
O método sort_index
ordena a Series ou o DataFrame pelo index. O método sort_values
ordena a Series ou o DataFrame pelos valores (escolhendo uma ou mais colunas no caso de DataFrames). No caso do DataFrame, o argumento by
é necessário para indicar qual(is) coluna(s) será(ão) utilizada(s) como base para a ordenação.
Exemplos:
serie_desordenada = pd.Series({'Maria': 21, 'Pedro': 22, 'Túlio': 20, 'João': 19, 'Ana':20});
serie_desordenada
Maria 21
Pedro 22
Túlio 20
João 19
Ana 20
dtype: int64
serie_desordenada.sort_index() # ordenação alfabética
Ana 20
João 19
Maria 21
Pedro 22
Túlio 20
dtype: int64
Mais exemplos:
df_desordenado = df_dict_series.reindex(index=['Pedro','Maria','Ana','Túlio','João'])
df_desordenado
Idade | Peso | Altura | |
---|---|---|---|
Pedro | 22 | 67 | 165 |
Maria | 21 | 62 | 162 |
Ana | 20 | 55 | 162 |
Túlio | 20 | 73 | 171 |
João | 19 | 80 | 178 |
df_desordenado.sort_index()
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
Mais exemplos:
serie_desordenada.sort_values()
João 19
Túlio 20
Ana 20
Maria 21
Pedro 22
dtype: int64
df_desordenado.sort_values(by=['Altura']) # ordena por 'Altura'
Idade | Peso | Altura | |
---|---|---|---|
Maria | 21 | 62 | 162 |
Ana | 20 | 55 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
João | 19 | 80 | 178 |
No caso de “empate”, podemos utilizar outra coluna para desempatar.
df_desordenado.sort_values(by=['Altura','Peso']) # usa a coluna 'Peso' para desempatar
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
João | 19 | 80 | 178 |
Os métodos sort_index
e sort_values
admitem o argumento opcional ascending
, que permite inverter a ordenação caso tenha valor False
.
df_desordenado.sort_index(ascending=False)
Idade | Peso | Altura | |
---|---|---|---|
Túlio | 20 | 73 | 171 |
Pedro | 22 | 67 | 165 |
Maria | 21 | 62 | 162 |
João | 19 | 80 | 178 |
Ana | 20 | 55 | 162 |
df_desordenado.sort_values(by=['Idade'], ascending=False)
Idade | Peso | Altura | |
---|---|---|---|
Pedro | 22 | 67 | 165 |
Maria | 21 | 62 | 162 |
Ana | 20 | 55 | 162 |
Túlio | 20 | 73 | 171 |
João | 19 | 80 | 178 |
Comparação de Series e DataFrames¶
Series e DataFrames possuem os seguintes métodos de comparação lógica:
eq
(igual);ne
(diferente);lt
(menor do que);gt
(maior do que);le
(menor ou igual a);ge
(maior ou igual a)
que permitem a utilização dos operadores binários ==
, !=
, <
, >
, <=
e >=
, respectivamente. As comparações são realizadas em cada entrada da Series ou do DataFrame.
Observação: Para que esses métodos sejam aplicados, todos os objetos presentes nas colunas do DataFrame devem ser de mesma natureza. Por exemplo, se um DataFrame possui algumas colunas numéricas e outras com strings, ao realizar uma comparação do tipo > 1
, um erro ocorrerá, pois o pandas tentará comparar objetos do tipo int
com objetos do tipo str
, assim gerando uma incompatibilidade.
Exemplos:
serie_exemplo
a 1
b 2
c 3
dtype: int64
serie_exemplo == 2
a False
b True
c False
dtype: bool
De outra forma:
serie_exemplo.eq(2)
a False
b True
c False
dtype: bool
serie_exemplo > 1
a False
b True
c True
dtype: bool
Ou, na forma funcional:
serie_exemplo.gt(1)
a False
b True
c True
dtype: bool
df_exemplo > 1
coluna_1 | coluna_2 | coluna_3 | |
---|---|---|---|
2020-01-01 | False | True | False |
2020-01-02 | False | True | True |
2020-01-03 | False | False | True |
2020-01-04 | False | True | True |
2020-01-05 | True | False | True |
2020-01-06 | False | False | True |
2020-01-07 | False | False | True |
2020-01-08 | False | False | True |
2020-01-09 | False | False | False |
2020-01-10 | False | False | False |
Importante: Ao comparar np.nan, o resultado tipicamente é falso:
np.nan == np.nan
False
np.nan > np.nan
False
np.nan >= np.nan
False
Só é verdadeiro para indicar que é diferente:
np.nan != np.nan
True
Neste sentido, podemos ter tabelas iguais sem que a comparação usual funcione:
# 'copy', como o nome sugere, gera uma cópia do DataFrame
df_exemplo_2 = df_exemplo.copy()
(df_exemplo == df_exemplo_2)
coluna_1 | coluna_2 | coluna_3 | |
---|---|---|---|
2020-01-01 | True | True | True |
2020-01-02 | True | True | True |
2020-01-03 | True | True | True |
2020-01-04 | True | True | True |
2020-01-05 | True | True | True |
2020-01-06 | True | True | True |
2020-01-07 | True | True | True |
2020-01-08 | True | True | True |
2020-01-09 | True | True | False |
2020-01-10 | True | True | False |
O motivo de haver entradas como False
ainda que df_exemplo_2
seja uma cópia exata de df_exemplo
é a presença do np.nan
. Neste caso, devemos utilizar o método equals
para realizar a comparação.
df_exemplo.equals(df_exemplo_2)
True
Os métodos any
, all
e a propriedade empty
¶
O método any
é aplicado a entradas booleanas (verdadeiras ou falsas) e retorna verdadeiro se existir alguma entrada verdadeira, ou falso, se todas forem falsas. O método all
é aplicado a entradas booleanas e retorna verdadeiro se todas as entradas forem verdadeiras, ou falso, se houver pelo menos uma entrada falsa. A propriedade empty
retorna verdadeiro se a Series ou o DataFrame estiver vazio, ou falso caso contrário.
Exemplos:
serie_exemplo
a 1
b 2
c 3
dtype: int64
serie_exemplo_2 = serie_exemplo-2;
serie_exemplo_2
a -1
b 0
c 1
dtype: int64
(serie_exemplo_2 > 0).any()
True
(serie_exemplo > 1).all()
False
Este exemplo reproduz um valor False
único.
(df_exemplo == df_exemplo_2).all().all()
False
serie_exemplo.empty
False
Mais exemplos:
(df_exemplo == df_exemplo_2).any()
coluna_1 True
coluna_2 True
coluna_3 True
dtype: bool
df_exemplo.empty
False
df_vazio = pd.DataFrame()
df_vazio.empty
True
Seleção de colunas de um DataFrame¶
Para selecionar colunas de um DataFrame, basta aplicar colchetes a uma lista contendo os nomes das colunas de interesse.
No exemplo abaixo, temos um DataFrame contendo as colunas 'Idade'
, 'Peso'
e 'Altura'
. Selecionaremos 'Peso'
e 'Altura'
, apenas.
df_dict_series[['Peso','Altura']]
Peso | Altura | |
---|---|---|
Ana | 55 | 162 |
João | 80 | 178 |
Maria | 62 | 162 |
Pedro | 67 | 165 |
Túlio | 73 | 171 |
Se quisermos selecionar apenas uma coluna, não há necessidade de inserir uma lista. Basta utilizar o nome da coluna:
df_dict_series['Peso']
Ana 55
João 80
Maria 62
Pedro 67
Túlio 73
Name: Peso, dtype: int64
Para remover colunas, podemos utilizar o método drop
.
df_dict_series.drop(['Peso','Altura'], axis=1)
Idade | |
---|---|
Ana | 20 |
João | 19 |
Maria | 21 |
Pedro | 22 |
Túlio | 20 |
Criação de novas colunas a partir de colunas existentes¶
Um método eficiente para criar novas colunas a partir de colunas já existentes é eval
. Neste método, podemos utilizar como argumento uma string contendo uma expressão matemática envolvendo nomes de colunas do DataFrame.
Como exemplo, vamos ver como calcular o IMC no DataFrame anterior:
df_dict_series.eval('Peso/(Altura/100)**2')
Ana 20.957171
João 25.249337
Maria 23.624447
Pedro 24.609734
Túlio 24.964946
dtype: float64
Se quisermos obter um DataFrame contendo o IMC como uma nova coluna, podemos utilizar o método assign
(sem modificar o DataFrame original):
df_dict_series.assign(IMC=round(df_dict_series.eval('Peso/(Altura/100)**2'),2))
Idade | Peso | Altura | IMC | |
---|---|---|---|---|
Ana | 20 | 55 | 162 | 20.96 |
João | 19 | 80 | 178 | 25.25 |
Maria | 21 | 62 | 162 | 23.62 |
Pedro | 22 | 67 | 165 | 24.61 |
Túlio | 20 | 73 | 171 | 24.96 |
df_dict_series # não modificado
Idade | Peso | Altura | |
---|---|---|---|
Ana | 20 | 55 | 162 |
João | 19 | 80 | 178 |
Maria | 21 | 62 | 162 |
Pedro | 22 | 67 | 165 |
Túlio | 20 | 73 | 171 |
Se quisermos modificar o DataFrame para incluir a coluna IMC fazemos:
df_dict_series['IMC']=round(df_dict_series.eval('Peso/(Altura/100)**2'),2)
df_dict_series # modificado "in-place"
Idade | Peso | Altura | IMC | |
---|---|---|---|---|
Ana | 20 | 55 | 162 | 20.96 |
João | 19 | 80 | 178 | 25.25 |
Maria | 21 | 62 | 162 | 23.62 |
Pedro | 22 | 67 | 165 | 24.61 |
Túlio | 20 | 73 | 171 | 24.96 |
Seleção de linhas de um DataFrame¶
Podemos selecionar linhas de um DataFrame de diversas formas diferentes. Veremos agora algumas dessas formas.
Diferentemente da forma de selecionar colunas, para selecionar diretamente linhas de um DataFrame devemos utilizar o método loc
(fornecendo o index, isto é, o rótulo da linha) ou o iloc
(fornecendo a posição da linha):
Trabalharemos a seguir com um banco de dados atualizado sobre a COVID-19. Para tanto, importaremos o módulo datetime
que nos auxiliará com datas.
import datetime
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)
# busca o banco na data D-1, visto que a atualização
# ocorre em D
ontem = (datetime.date.today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
dados_covid_PB.head(1)
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2021-09-26 | 441155 | 134 | 484336 | 333751 | 9294 | 2.0 | 0.0211 |
Podemos ver as informações de um único dia como argumento. Para tanto, excluímos a coluna 'Letalidade'
(valor não inteiro) e convertemos o restante para valores inteiros:
dados_covid_PB.loc[ontem].drop('Letalidade').astype('int')
casosAcumulados 441155
casosNovos 134
descartados 484336
recuperados 333751
obitosAcumulados 9294
obitosNovos 2
Name: 2021-09-26, dtype: int64
Podemos selecionar um intervalo de datas como argumento (excluindo letalidade):
dados_covid_PB.index = pd.to_datetime(dados_covid_PB.index) # Convertendo o index de string para data
dados_covid_PB.loc[pd.date_range('2021-02-01',periods=5,freq="D")].drop('Letalidade',axis=1)
#função pd.date_range é muito útil para criar índices a partir de datas.
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | |
---|---|---|---|---|---|---|
2021-02-01 | 192598 | 1014 | 234215 | 149235 | 4068 | 12.0 |
2021-02-02 | 193465 | 867 | 234366 | 149242 | 4082 | 14.0 |
2021-02-03 | 194519 | 1054 | 234902 | 149248 | 4096 | 14.0 |
2021-02-04 | 195482 | 963 | 235319 | 149792 | 4110 | 14.0 |
2021-02-05 | 196542 | 1060 | 236216 | 150169 | 4123 | 13.0 |
Podemos colocar uma lista como argumento:
dados_covid_PB.loc[pd.to_datetime(['2021-01-01','2021-02-01'])]
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
2021-01-01 | 167062 | 578 | 219890 | 127388 | 3680 | 8.0 | 0.0220 |
2021-02-01 | 192598 | 1014 | 234215 | 149235 | 4068 | 12.0 | 0.0211 |
Vamos agora examinar os dados da posição 100 (novamente excluindo a coluna letalidade e convertendo para inteiro):
dados_covid_PB.iloc[100].drop('Letalidade').astype('int')
casosAcumulados 371133
casosNovos 2555
descartados 328941
recuperados 243203
obitosAcumulados 8316
obitosNovos 47
Name: 2021-06-18 00:00:00, dtype: int64
Podemos colocar um intervalo como argumento:
dados_covid_PB.iloc[50:55].drop('Letalidade', axis=1).astype('int')
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | |
---|---|---|---|---|---|---|
data | ||||||
2021-08-07 | 424983 | 406 | 456236 | 298889 | 9049 | 12 |
2021-08-06 | 424577 | 423 | 455493 | 298554 | 9037 | 14 |
2021-08-05 | 424154 | 570 | 454357 | 297945 | 9023 | 5 |
2021-08-04 | 423584 | 872 | 453146 | 297222 | 9018 | 7 |
2021-08-03 | 422712 | 37 | 451358 | 296180 | 9011 | 8 |
Seleção de colunas com loc
e iloc
¶
Podemos selecionar colunas utilizando os métodos loc
e iloc
utilizando um argumento adicional.
dados_covid_PB.loc[:,['casosNovos','obitosNovos']]
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
dados_covid_PB.iloc[:,4:6] # fatiamento na coluna
obitosAcumulados | obitosNovos | |
---|---|---|
data | ||
2021-09-26 | 9294 | 2.0 |
2021-09-25 | 9292 | 2.0 |
2021-09-24 | 9290 | 3.0 |
2021-09-23 | 9287 | 3.0 |
2021-09-22 | 9284 | 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
Seleção de linhas e colunas específicas com loc
e iloc
¶
Usando o mesmo princípio de fatiamento aplicado a arrays do numpy, podemos selecionar linhas e colunas em um intervalo específico de forma a obter uma subtabela.
dados_covid_PB.iloc[95:100,4:6]
obitosAcumulados | obitosNovos | |
---|---|---|
data | ||
2021-06-23 | 8453 | 20.0 |
2021-06-22 | 8433 | 22.0 |
2021-06-21 | 8411 | 30.0 |
2021-06-20 | 8381 | 33.0 |
2021-06-19 | 8348 | 32.0 |
Neste exemplo um pouco mais complexo, buscamos casos novos e óbitos novos em um período específico e ordenamos a tabela da data mais recente para a mais antiga.
dados_covid_PB.loc[pd.date_range('2020-04-06','2020-04-10'),['casosNovos','obitosNovos']].sort_index(ascending=False)
casosNovos | obitosNovos | |
---|---|---|
2020-04-10 | 6 | 0.0 |
2020-04-09 | 24 | 4.0 |
2020-04-08 | 14 | 3.0 |
2020-04-07 | 5 | 0.0 |
2020-04-06 | 1 | 0.0 |
Suponha que o peso de Ana foi medido corretamente, mas registrado de maneira errônea no DataFrame df_dict_series
como 55.
df_dict_series
Idade | Peso | Altura | IMC | |
---|---|---|---|---|
Ana | 20 | 55 | 162 | 20.96 |
João | 19 | 80 | 178 | 25.25 |
Maria | 21 | 62 | 162 | 23.62 |
Pedro | 22 | 67 | 165 | 24.61 |
Túlio | 20 | 73 | 171 | 24.96 |
Supondo que, na realidade, o valor é 65, alteramos a entrada específica com um simples loc
. Em seguida, atualizamos a tabela.
df_dict_series.loc['Ana','Peso'] = 65
df_dict_series = df_dict_series.assign(IMC=round(df_dict_series.eval('Peso/(Altura/100)**2'),2)) # O IMC mudou
df_dict_series
Idade | Peso | Altura | IMC | |
---|---|---|---|---|
Ana | 20 | 65 | 162 | 24.77 |
João | 19 | 80 | 178 | 25.25 |
Maria | 21 | 62 | 162 | 23.62 |
Pedro | 22 | 67 | 165 | 24.61 |
Túlio | 20 | 73 | 171 | 24.96 |
Seleção de linhas através de critérios lógicos ou funções¶
Vamos selecionar quais os dias em que houve mais de 40 mortes registradas:
dados_covid_PB.loc[dados_covid_PB['obitosNovos']>40]
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2021-06-18 | 371133 | 2555 | 328941 | 243203 | 8316 | 47.0 | 0.0224 |
2021-06-11 | 354715 | 2451 | 322301 | 235778 | 8058 | 55.0 | 0.0227 |
2021-06-10 | 352264 | 3911 | 231258 | 235329 | 8003 | 46.0 | 0.0227 |
2021-04-27 | 289319 | 1037 | 290111 | 204340 | 6722 | 46.0 | 0.0232 |
2021-04-19 | 280967 | 904 | 286168 | 194644 | 6487 | 43.0 | 0.0231 |
2021-04-14 | 275301 | 1218 | 282121 | 193451 | 6316 | 42.0 | 0.0229 |
2021-04-12 | 272811 | 1486 | 279801 | 193188 | 6234 | 58.0 | 0.0229 |
2021-04-07 | 267008 | 1551 | 274623 | 189753 | 6050 | 49.0 | 0.0227 |
2021-04-06 | 265457 | 817 | 273026 | 186879 | 6001 | 52.0 | 0.0226 |
2021-04-05 | 264640 | 1059 | 272719 | 186670 | 5949 | 43.0 | 0.0225 |
2021-04-03 | 262500 | 789 | 272207 | 186334 | 5866 | 46.0 | 0.0223 |
2021-04-01 | 260484 | 1311 | 271069 | 186084 | 5791 | 47.0 | 0.0222 |
2021-03-31 | 259173 | 1553 | 270560 | 183668 | 5744 | 73.0 | 0.0222 |
2021-03-30 | 257620 | 1150 | 269399 | 183369 | 5671 | 70.0 | 0.0220 |
2021-03-29 | 256470 | 968 | 268985 | 183028 | 5601 | 49.0 | 0.0218 |
2021-03-28 | 255502 | 1203 | 268866 | 182873 | 5552 | 43.0 | 0.0217 |
2021-03-27 | 254299 | 1410 | 268309 | 182680 | 5509 | 57.0 | 0.0217 |
2021-03-26 | 252889 | 1611 | 266785 | 182404 | 5452 | 48.0 | 0.0216 |
2021-03-25 | 251278 | 1672 | 265533 | 180125 | 5404 | 50.0 | 0.0215 |
2021-03-24 | 249606 | 1154 | 264150 | 177812 | 5354 | 41.0 | 0.0214 |
2021-03-23 | 248452 | 1140 | 264146 | 177591 | 5313 | 41.0 | 0.0214 |
2021-03-20 | 245564 | 1300 | 264128 | 174980 | 5212 | 45.0 | 0.0212 |
2021-03-19 | 244264 | 1269 | 264122 | 174769 | 5167 | 44.0 | 0.0212 |
2021-03-18 | 242995 | 1403 | 258188 | 172789 | 5123 | 43.0 | 0.0211 |
2021-03-17 | 241592 | 1194 | 256574 | 172492 | 5080 | 44.0 | 0.0210 |
2021-03-16 | 240398 | 804 | 255491 | 172218 | 5036 | 44.0 | 0.0209 |
2021-03-15 | 239594 | 1025 | 255162 | 171911 | 4992 | 59.0 | 0.0208 |
2021-03-10 | 232771 | 1365 | 251742 | 170510 | 4797 | 50.0 | 0.0206 |
2021-03-04 | 225672 | 1385 | 245919 | 164712 | 4612 | 54.0 | 0.0204 |
2020-07-21 | 68844 | 1164 | 78605 | 25028 | 1558 | 41.0 | 0.0226 |
2020-07-15 | 63939 | 1477 | 74399 | 23695 | 1383 | 41.0 | 0.0216 |
2020-07-02 | 49536 | 1361 | 48272 | 16349 | 1044 | 42.0 | 0.0211 |
2020-06-30 | 46957 | 1900 | 43070 | 14930 | 977 | 46.0 | 0.0208 |
Selecionando os dias com mais de 25 óbitos e mais de 1500 casos novos:
dados_covid_PB.loc[(dados_covid_PB.obitosNovos > 25) & (dados_covid_PB.casosNovos>1500)]
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2021-07-02 | 398440 | 1536 | 332530 | 262757 | 8654 | 26.0 | 0.0217 |
2021-06-24 | 385018 | 2391 | 332313 | 250519 | 8479 | 26.0 | 0.0220 |
2021-06-21 | 378064 | 2114 | 330969 | 249135 | 8411 | 30.0 | 0.0222 |
2021-06-20 | 375950 | 2178 | 330721 | 248667 | 8381 | 33.0 | 0.0223 |
2021-06-19 | 373772 | 2639 | 329903 | 248304 | 8348 | 32.0 | 0.0223 |
2021-06-18 | 371133 | 2555 | 328941 | 243203 | 8316 | 47.0 | 0.0224 |
2021-06-17 | 368578 | 2457 | 327929 | 242820 | 8269 | 32.0 | 0.0224 |
2021-06-16 | 366121 | 2328 | 326517 | 242184 | 8237 | 40.0 | 0.0225 |
2021-06-15 | 363793 | 2358 | 325032 | 241749 | 8197 | 39.0 | 0.0225 |
2021-06-14 | 361435 | 2575 | 324438 | 241293 | 8158 | 30.0 | 0.0226 |
2021-06-13 | 358860 | 2034 | 324327 | 236555 | 8128 | 33.0 | 0.0226 |
2021-06-12 | 356826 | 2111 | 323444 | 236186 | 8095 | 37.0 | 0.0227 |
2021-06-11 | 354715 | 2451 | 322301 | 235778 | 8058 | 55.0 | 0.0227 |
2021-06-10 | 352264 | 3911 | 231258 | 235329 | 8003 | 46.0 | 0.0227 |
2021-06-06 | 344174 | 1982 | 319055 | 230002 | 7849 | 29.0 | 0.0228 |
2021-06-05 | 342192 | 1992 | 318096 | 229790 | 7820 | 29.0 | 0.0229 |
2021-06-04 | 340200 | 2421 | 317390 | 229489 | 7791 | 26.0 | 0.0229 |
2021-06-03 | 337779 | 2660 | 316011 | 229062 | 7765 | 30.0 | 0.0230 |
2021-06-02 | 335119 | 2403 | 314538 | 225278 | 7735 | 32.0 | 0.0231 |
2021-06-01 | 332716 | 1751 | 314520 | 224912 | 7703 | 31.0 | 0.0232 |
2021-05-29 | 328771 | 2429 | 312011 | 224255 | 7617 | 28.0 | 0.0232 |
2021-05-28 | 326342 | 1917 | 311013 | 223896 | 7589 | 33.0 | 0.0233 |
2021-05-27 | 324425 | 1887 | 310639 | 223537 | 7556 | 36.0 | 0.0233 |
2021-05-26 | 322538 | 2262 | 309492 | 221134 | 7520 | 36.0 | 0.0233 |
2021-05-25 | 320276 | 2015 | 308275 | 220621 | 7484 | 36.0 | 0.0234 |
2021-04-07 | 267008 | 1551 | 274623 | 189753 | 6050 | 49.0 | 0.0227 |
2021-03-31 | 259173 | 1553 | 270560 | 183668 | 5744 | 73.0 | 0.0222 |
2021-03-26 | 252889 | 1611 | 266785 | 182404 | 5452 | 48.0 | 0.0216 |
2021-03-25 | 251278 | 1672 | 265533 | 180125 | 5404 | 50.0 | 0.0215 |
2021-03-13 | 237313 | 1694 | 254238 | 171130 | 4896 | 31.0 | 0.0206 |
2020-08-04 | 85760 | 1549 | 106500 | 38554 | 1901 | 31.0 | 0.0222 |
2020-07-31 | 82794 | 1686 | 96753 | 35971 | 1811 | 26.0 | 0.0219 |
2020-07-23 | 73104 | 2132 | 84047 | 28566 | 1618 | 37.0 | 0.0221 |
2020-07-10 | 59118 | 1504 | 69567 | 21481 | 1229 | 33.0 | 0.0208 |
2020-07-08 | 56344 | 1542 | 67549 | 19999 | 1171 | 26.0 | 0.0208 |
2020-07-07 | 54802 | 1651 | 64933 | 19373 | 1145 | 27.0 | 0.0209 |
2020-06-30 | 46957 | 1900 | 43070 | 14930 | 977 | 46.0 | 0.0208 |
2020-06-09 | 22452 | 1501 | 20650 | 4671 | 534 | 27.0 | 0.0238 |
Obs.: Note que podemos utilizar o nome da coluna como um atributo.
Vamos inserir uma coluna sobrenome no df_dict_series
:
df_dict_series['Sobrenome'] = ['Silva', 'PraDo', 'Sales', 'MachadO', 'Coutinho']
df_dict_series
Idade | Peso | Altura | IMC | Sobrenome | |
---|---|---|---|---|---|
Ana | 20 | 65 | 162 | 24.77 | Silva |
João | 19 | 80 | 178 | 25.25 | PraDo |
Maria | 21 | 62 | 162 | 23.62 | Sales |
Pedro | 22 | 67 | 165 | 24.61 | MachadO |
Túlio | 20 | 73 | 171 | 24.96 | Coutinho |
Vamos encontrar as linhas cujo sobrenome termina em “do”. Para tanto, note que a função abaixo retorna True
se o final é “do” e False
caso contrário.
def verifica_final_do(palavra):
return palavra.lower()[-2:] == 'do'
Obs.: Note que convertemos tudo para minúsculo.
Agora vamos utilizar essa função para alcançar nosso objetivo:
# 'map' aplica a função lambda a cada elemento da *Series*
df_dict_series['Sobrenome'].map(lambda palavra: palavra.lower()[-2:]=='do')
Ana False
João True
Maria False
Pedro True
Túlio False
Name: Sobrenome, dtype: bool
# procurando no df inteiro
df_dict_series.loc[df_dict_series['Sobrenome'].map(lambda palavra: palavra.lower()[-2:]=='do')]
Idade | Peso | Altura | IMC | Sobrenome | |
---|---|---|---|---|---|
João | 19 | 80 | 178 | 25.25 | PraDo |
Pedro | 22 | 67 | 165 | 24.61 | MachadO |
Vamos selecionar as linhas do mês 2 (fevereiro) usando index.month
:
dados_covid_PB.loc[dados_covid_PB.index.month==2].head()
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2021-02-28 | 221115 | 1392 | 245686 | 158304 | 4496 | 25.0 | 0.0203 |
2021-02-27 | 219723 | 1416 | 245121 | 158132 | 4471 | 20.0 | 0.0203 |
2021-02-26 | 218307 | 1186 | 244356 | 157849 | 4451 | 18.0 | 0.0204 |
2021-02-25 | 217121 | 1594 | 243890 | 157586 | 4433 | 14.0 | 0.0204 |
2021-02-24 | 215527 | 1320 | 243253 | 157329 | 4419 | 15.0 | 0.0205 |
Seleção de linhas com o método query¶
Similarmente ao método eval
, ao utilizarmos query
, podemos criar expressões lógicas a partir de nomes das colunas do DataFrame.
Assim, podemos reescrever o código
dados_covid_PB.loc[(dados_covid_PB.obitosNovos>25) &
(dados_covid_PB.casosNovos>1500)]
como
dados_covid_PB.query('obitosNovos>25 and casosNovos>1500') # note que 'and' é usado em vez de '&'
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2021-07-02 | 398440 | 1536 | 332530 | 262757 | 8654 | 26.0 | 0.0217 |
2021-06-24 | 385018 | 2391 | 332313 | 250519 | 8479 | 26.0 | 0.0220 |
2021-06-21 | 378064 | 2114 | 330969 | 249135 | 8411 | 30.0 | 0.0222 |
2021-06-20 | 375950 | 2178 | 330721 | 248667 | 8381 | 33.0 | 0.0223 |
2021-06-19 | 373772 | 2639 | 329903 | 248304 | 8348 | 32.0 | 0.0223 |
2021-06-18 | 371133 | 2555 | 328941 | 243203 | 8316 | 47.0 | 0.0224 |
2021-06-17 | 368578 | 2457 | 327929 | 242820 | 8269 | 32.0 | 0.0224 |
2021-06-16 | 366121 | 2328 | 326517 | 242184 | 8237 | 40.0 | 0.0225 |
2021-06-15 | 363793 | 2358 | 325032 | 241749 | 8197 | 39.0 | 0.0225 |
2021-06-14 | 361435 | 2575 | 324438 | 241293 | 8158 | 30.0 | 0.0226 |
2021-06-13 | 358860 | 2034 | 324327 | 236555 | 8128 | 33.0 | 0.0226 |
2021-06-12 | 356826 | 2111 | 323444 | 236186 | 8095 | 37.0 | 0.0227 |
2021-06-11 | 354715 | 2451 | 322301 | 235778 | 8058 | 55.0 | 0.0227 |
2021-06-10 | 352264 | 3911 | 231258 | 235329 | 8003 | 46.0 | 0.0227 |
2021-06-06 | 344174 | 1982 | 319055 | 230002 | 7849 | 29.0 | 0.0228 |
2021-06-05 | 342192 | 1992 | 318096 | 229790 | 7820 | 29.0 | 0.0229 |
2021-06-04 | 340200 | 2421 | 317390 | 229489 | 7791 | 26.0 | 0.0229 |
2021-06-03 | 337779 | 2660 | 316011 | 229062 | 7765 | 30.0 | 0.0230 |
2021-06-02 | 335119 | 2403 | 314538 | 225278 | 7735 | 32.0 | 0.0231 |
2021-06-01 | 332716 | 1751 | 314520 | 224912 | 7703 | 31.0 | 0.0232 |
2021-05-29 | 328771 | 2429 | 312011 | 224255 | 7617 | 28.0 | 0.0232 |
2021-05-28 | 326342 | 1917 | 311013 | 223896 | 7589 | 33.0 | 0.0233 |
2021-05-27 | 324425 | 1887 | 310639 | 223537 | 7556 | 36.0 | 0.0233 |
2021-05-26 | 322538 | 2262 | 309492 | 221134 | 7520 | 36.0 | 0.0233 |
2021-05-25 | 320276 | 2015 | 308275 | 220621 | 7484 | 36.0 | 0.0234 |
2021-04-07 | 267008 | 1551 | 274623 | 189753 | 6050 | 49.0 | 0.0227 |
2021-03-31 | 259173 | 1553 | 270560 | 183668 | 5744 | 73.0 | 0.0222 |
2021-03-26 | 252889 | 1611 | 266785 | 182404 | 5452 | 48.0 | 0.0216 |
2021-03-25 | 251278 | 1672 | 265533 | 180125 | 5404 | 50.0 | 0.0215 |
2021-03-13 | 237313 | 1694 | 254238 | 171130 | 4896 | 31.0 | 0.0206 |
2020-08-04 | 85760 | 1549 | 106500 | 38554 | 1901 | 31.0 | 0.0222 |
2020-07-31 | 82794 | 1686 | 96753 | 35971 | 1811 | 26.0 | 0.0219 |
2020-07-23 | 73104 | 2132 | 84047 | 28566 | 1618 | 37.0 | 0.0221 |
2020-07-10 | 59118 | 1504 | 69567 | 21481 | 1229 | 33.0 | 0.0208 |
2020-07-08 | 56344 | 1542 | 67549 | 19999 | 1171 | 26.0 | 0.0208 |
2020-07-07 | 54802 | 1651 | 64933 | 19373 | 1145 | 27.0 | 0.0209 |
2020-06-30 | 46957 | 1900 | 43070 | 14930 | 977 | 46.0 | 0.0208 |
2020-06-09 | 22452 | 1501 | 20650 | 4671 | 534 | 27.0 | 0.0238 |