Operações com 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
Criando 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.
Criando um 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 |
Criando um 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 |
Criando um 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 |
Criando um 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 |
Criando um 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('data/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('data/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('data/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: 331 entries, 2021-02-09 to 2020-03-16
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 casosAcumulados 331 non-null int64
1 casosNovos 331 non-null int64
2 descartados 331 non-null int64
3 recuperados 331 non-null int64
4 obitosAcumulados 331 non-null int64
5 obitosNovos 331 non-null int64
6 Letalidade 331 non-null float64
dtypes: float64(1), int64(6)
memory usage: 20.7+ KB
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 |
dados_covid_PB.tail()
casosAcumulados | casosNovos | descartados | recuperados | obitosAcumulados | obitosNovos | Letalidade | |
---|---|---|---|---|---|---|---|
data | |||||||
2020-03-20 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 |
2020-03-19 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 |
2020-03-18 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 |
2020-03-17 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 |
2020-03-16 | 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-02-09 | 199706 | 971 | 237369 | 152779 | 4171 | 13 | 0.0209 | PB |
2021-02-08 | 198735 | 611 | 237189 | 151879 | 4158 | 12 | 0.0209 | PB |
2021-02-07 | 198124 | 664 | 237072 | 151535 | 4146 | 11 | 0.0209 | PB |
2021-02-06 | 197460 | 918 | 236774 | 150175 | 4135 | 12 | 0.0209 | PB |
2021-02-05 | 196542 | 1060 | 236216 | 150169 | 4123 | 13 | 0.0210 | PB |
dados_covid_PB.to_csv('data/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('data/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 |
Ordenando 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 |
Comparando 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
Selecionando 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 |
Criando 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 |
Selecionando 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-02-09 | 199706 | 971 | 237369 | 152779 | 4171 | 13 | 0.0209 |
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 199706
casosNovos 971
descartados 237369
recuperados 152779
obitosAcumulados 4171
obitosNovos 13
Name: 2021-02-09, 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 |
2021-02-02 | 193465 | 867 | 234366 | 149242 | 4082 | 14 |
2021-02-03 | 194519 | 1054 | 234902 | 149248 | 4096 | 14 |
2021-02-04 | 195482 | 963 | 235319 | 149792 | 4110 | 14 |
2021-02-05 | 196542 | 1060 | 236216 | 150169 | 4123 | 13 |
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.0220 |
2021-02-01 | 192598 | 1014 | 234215 | 149235 | 4068 | 12 | 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 133220
casosNovos 71
descartados 185162
recuperados 108737
obitosAcumulados 3107
obitosNovos 6
Name: 2020-11-01 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 | ||||||
2020-12-21 | 159639 | 203 | 213617 | 123430 | 3552 | 13 |
2020-12-20 | 159436 | 327 | 213356 | 123417 | 3539 | 10 |
2020-12-19 | 159109 | 660 | 213149 | 123295 | 3529 | 6 |
2020-12-18 | 158449 | 1053 | 212439 | 122935 | 3523 | 16 |
2020-12-17 | 157396 | 1274 | 210628 | 122219 | 3507 | 20 |
Selecionando colunas pelos métodos 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-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
dados_covid_PB.iloc[:,4:6] # fatiamento na coluna
obitosAcumulados | obitosNovos | |
---|---|---|
data | ||
2021-02-09 | 4171 | 13 |
2021-02-08 | 4158 | 12 |
2021-02-07 | 4146 | 11 |
2021-02-06 | 4135 | 12 |
2021-02-05 | 4123 | 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
Selecionando linhas e colunas específicas pelos métodos 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 | ||
2020-11-06 | 3146 | 8 |
2020-11-05 | 3138 | 8 |
2020-11-04 | 3130 | 11 |
2020-11-03 | 3119 | 11 |
2020-11-02 | 3108 | 1 |
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 |
2020-04-09 | 24 | 4 |
2020-04-08 | 14 | 3 |
2020-04-07 | 5 | 0 |
2020-04-06 | 1 | 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 |
Selecionando linha 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 | |||||||
2020-07-21 | 68844 | 1164 | 78605 | 25028 | 1558 | 41 | 0.0226 |
2020-07-15 | 63939 | 1477 | 74399 | 23695 | 1383 | 41 | 0.0216 |
2020-07-02 | 49536 | 1361 | 48272 | 16349 | 1044 | 42 | 0.0211 |
2020-06-30 | 46957 | 1900 | 43070 | 14930 | 977 | 46 | 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 | |||||||
2020-08-04 | 85760 | 1549 | 106500 | 38554 | 1901 | 31 | 0.0222 |
2020-07-31 | 82794 | 1686 | 96753 | 35971 | 1811 | 26 | 0.0219 |
2020-07-23 | 73104 | 2132 | 84047 | 28566 | 1618 | 37 | 0.0221 |
2020-07-10 | 59118 | 1504 | 69567 | 21481 | 1229 | 33 | 0.0208 |
2020-07-08 | 56344 | 1542 | 67549 | 19999 | 1171 | 26 | 0.0208 |
2020-07-07 | 54802 | 1651 | 64933 | 19373 | 1145 | 27 | 0.0209 |
2020-06-30 | 46957 | 1900 | 43070 | 14930 | 977 | 46 | 0.0208 |
2020-06-09 | 22452 | 1501 | 20650 | 4671 | 534 | 27 | 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-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 |
Selecionando 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 | |||||||
2020-08-04 | 85760 | 1549 | 106500 | 38554 | 1901 | 31 | 0.0222 |
2020-07-31 | 82794 | 1686 | 96753 | 35971 | 1811 | 26 | 0.0219 |
2020-07-23 | 73104 | 2132 | 84047 | 28566 | 1618 | 37 | 0.0221 |
2020-07-10 | 59118 | 1504 | 69567 | 21481 | 1229 | 33 | 0.0208 |
2020-07-08 | 56344 | 1542 | 67549 | 19999 | 1171 | 26 | 0.0208 |
2020-07-07 | 54802 | 1651 | 64933 | 19373 | 1145 | 27 | 0.0209 |
2020-06-30 | 46957 | 1900 | 43070 | 14930 | 977 | 46 | 0.0208 |
2020-06-09 | 22452 | 1501 | 20650 | 4671 | 534 | 27 | 0.0238 |