Manipulação de Dados com Pandas

Author

Vinícius Oviedo

Slicing e filtros

Nesta aula, vamos trabalhar com um conjunto de dados sobre o preço dos serviços de streaming. Veremos alguns métodos pandas para:

  1. Selecionar colunas
  2. Eliminar colunas
  3. Realizar slicing (linhas, colunas)
  4. Realizar slicing lógico (condições)
  5. Realizar consultas SQL
  6. Aplicar outros filtros de colunas

Antes, precisamos importar a biblioteca e carregar os dados.

import pandas as pd

preco_streamings = pd.read_excel('dados/preco_servicos_streaming/Streaming_prices.xlsx')
preco_streamings.head(2)
Streaming service Reference date Price (USD)
0 Netflix Jul-2011 7.99
1 Netflix Aug-2011 7.99

1. Selecionar colunas

Uma maneira simples de selecionar colunas é especificar quais colunas se quer filtrar utilizando colchetes duplos ([['coluna A', 'coluna B', 'coluna N']]).

preco_streamings[['Streaming service', 'Price (USD)']]
Streaming service Price (USD)
0 Netflix 7.99
1 Netflix 7.99
2 Netflix 7.99
3 Netflix 7.99
4 Netflix 7.99
... ... ...
499 Apple TV+ 6.99
500 Apple TV+ 6.99
501 Apple TV+ 6.99
502 Apple TV+ 6.99
503 Apple TV+ 9.99

504 rows × 2 columns

Inclusive, é possível salvar essa seleção em outro dataframe (ou variável): `

streaming_e_preco = preco_streamings[['Streaming service', 'Price (USD)']]
streaming_e_preco.tail(3)
Streaming service Price (USD)
501 Apple TV+ 6.99
502 Apple TV+ 6.99
503 Apple TV+ 9.99

2. Eliminar colunas

Vamos supor que eu queria trabalhar apenas com a lista de streamings disponíveis no dataset. Uma maneira de fazer isso é:

  1. Listar as duplicatas de Streaming service
  2. Eliminar as demais colunas.

Para isso, podemos usar os métodos .drop_duplicates() e o método .drop() - este último tem como opções indicar o eixo (0: linhas, 1: colunas) e o paramêtro inplace=True, que permite sobreescrever o dataframe.

# Listando os serviços de streaming (sem duplicatas) e as demais colunas:
streamings = preco_streamings.drop_duplicates(subset='Streaming service')

# Elimiando as colunas de data e preço:
streamings.drop(['Reference date', 'Price (USD)'], axis=1, inplace=True)
streamings
Streaming service
0 Netflix
151 Disney+
202 HBO Max
247 Paramount+
359 Prime Video
453 Apple TV+

3. Slicing com loc e iloc

Os métodos mencionados no título da seção são muito eficazes e permitem selecionar linhas e também a combinação de linhas e colunas.

# loc (selecionar linhas)
df.loc[i]

# iloc (selecionar linhas e colunas)
df.iloc[i,j]

Para melhor entendimento, vejamos alguns exemploa:

Linha 20 (lembre que os índices começam em 0)

preco_streamings.loc[19]
Streaming service     Netflix
Reference date       Feb-2013
Price (USD)              7.99
Name: 19, dtype: object

Índices 400-405

# linha 20 (lembre que os índices começam em 0)
preco_streamings.loc[400:405]
Streaming service Reference date Price (USD)
400 Prime Video Sep-2019 8.99
401 Prime Video Oct-2019 8.99
402 Prime Video Nov-2019 8.99
403 Prime Video Dec-2019 8.99
404 Prime Video Jan-2020 8.99
405 Prime Video Feb-2020 8.99

Linhas e colunas

# indices 10:14 (10, n-1) e coluna 3 (preço):
preco_streamings.iloc[10:16, 2]
10    7.99
11    7.99
12    7.99
13    7.99
14    7.99
15    7.99
Name: Price (USD), dtype: float64

4. Slicing lógico (condições)

Podemos aplicar condições durante o slicing em um dataframe.

# condição:
condicao = preco_streamings['Streaming service'] == 'Prime Video'

# slicing (apenas Prime Video):
preco_streamings[condicao]
Streaming service Reference date Price (USD)
359 Prime Video Apr-2016 8.99
360 Prime Video May-2016 8.99
361 Prime Video Jun-2016 8.99
362 Prime Video Jul-2016 8.99
363 Prime Video Aug-2016 8.99
... ... ... ...
448 Prime Video Sep-2023 8.99
449 Prime Video Oct-2023 8.99
450 Prime Video Nov-2023 8.99
451 Prime Video Dec-2023 8.99
452 Prime Video Jan-2024 11.99

94 rows × 3 columns

Certamente, isso pode ser realizado em uma única linha de código também:

# slicing (todos os streamings menos Prime Video):
preco_streamings[preco_streamings['Streaming service'] != 'Prime Video']
Streaming service Reference date Price (USD)
0 Netflix Jul-2011 7.99
1 Netflix Aug-2011 7.99
2 Netflix Sep-2011 7.99
3 Netflix Oct-2011 7.99
4 Netflix Nov-2011 7.99
... ... ... ...
499 Apple TV+ Sep-2023 6.99
500 Apple TV+ Oct-2023 6.99
501 Apple TV+ Nov-2023 6.99
502 Apple TV+ Dec-2023 6.99
503 Apple TV+ Jan-2024 9.99

410 rows × 3 columns

Outro exemplo seria:

# condição:
condicao_A = preco_streamings['Streaming service'] == 'Prime Video' 
condicao_B = preco_streamings['Streaming service'] == 'Disney+'

# slicing (streamings: Prime Video ou Disney+ ):
preco_streamings[condicao_A | condicao_B]
Streaming service Reference date Price (USD)
151 Disney+ Nov-2019 6.99
152 Disney+ Dec-2019 6.99
153 Disney+ Jan-2020 6.99
154 Disney+ Feb-2020 6.99
155 Disney+ Mar-2020 6.99
... ... ... ...
448 Prime Video Sep-2023 8.99
449 Prime Video Oct-2023 8.99
450 Prime Video Nov-2023 8.99
451 Prime Video Dec-2023 8.99
452 Prime Video Jan-2024 11.99

145 rows × 3 columns

5. Consultas SQL com o query()

Podemos utilizar de expressões muito similares a linguagem SQL.

#query
df.query(<expressão>)

Vejamos alguns exemplos que ilustram as possibilidades desse método.

preco_streamings.query(' `Price (USD)` >= 7.99 & `Price (USD)` < 11.99')
Streaming service Reference date Price (USD)
0 Netflix Jul-2011 7.99
1 Netflix Aug-2011 7.99
2 Netflix Sep-2011 7.99
3 Netflix Oct-2011 7.99
4 Netflix Nov-2011 7.99
... ... ... ...
448 Prime Video Sep-2023 8.99
449 Prime Video Oct-2023 8.99
450 Prime Video Nov-2023 8.99
451 Prime Video Dec-2023 8.99
503 Apple TV+ Jan-2024 9.99

376 rows × 3 columns

preco_streamings.query(' `Reference date` == "Jan-2024" ')
Streaming service Reference date Price (USD)
150 Netflix Jan-2024 15.49
201 Disney+ Jan-2024 13.99
246 HBO Max Jan-2024 15.99
358 Paramount+ Jan-2024 11.99
452 Prime Video Jan-2024 11.99
503 Apple TV+ Jan-2024 9.99
# Listando interesses:
streamings_de_interesse = ['Paramount+', 'Netflix']

# Realizando a consulta:
consulta = preco_streamings.query(' `Streaming service` in @streamings_de_interesse ')
consulta
Streaming service Reference date Price (USD)
0 Netflix Jul-2011 7.99
1 Netflix Aug-2011 7.99
2 Netflix Sep-2011 7.99
3 Netflix Oct-2011 7.99
4 Netflix Nov-2011 7.99
... ... ... ...
354 Paramount+ Sep-2023 11.99
355 Paramount+ Oct-2023 11.99
356 Paramount+ Nov-2023 11.99
357 Paramount+ Dec-2023 11.99
358 Paramount+ Jan-2024 11.99

263 rows × 3 columns

6. Outros filtros de coluna

Vejamos outros tipos de filtros de coluna utilizando o cojunto de dados de vendas:

Filter

O método .filter() é muito útil em algumas situações.

vendas_europa = pd.read_csv('dados/vendas/EuropeSalesRecords.csv')
vendas_europa
Region Country Item Type Sales Channel Order Priority Order Date Order ID Ship Date Units Sold Unit Price Unit Cost Total Revenue Total Cost Total Profit
0 Europe Czech Republic Beverages Offline C 9/12/2011 478051030 9/29/2011 4778 47.45 31.79 226716.10 151892.62 74823.48
1 Europe Bosnia and Herzegovina Clothes Online M 10/14/2013 919133651 11/4/2013 927 109.28 35.84 101302.56 33223.68 68078.88
2 Europe Austria Cereal Offline C 8/13/2014 987410676 9/6/2014 5616 205.70 117.11 1155211.20 657689.76 497521.44
3 Europe Bulgaria Office Supplies Online L 10/31/2010 672330081 11/29/2010 6266 651.21 524.96 4080481.86 3289399.36 791082.50
4 Europe Estonia Fruits Online L 9/28/2016 579463422 11/1/2016 4958 9.33 6.92 46258.14 34309.36 11948.78
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1325 Europe Norway Personal Care Offline M 1/14/2014 634033286 1/15/2014 3394 81.73 56.67 277391.62 192337.98 85053.64
1326 Europe Ukraine Cereal Offline L 4/14/2014 559183347 5/21/2014 3633 205.70 117.11 747308.10 425460.63 321847.47
1327 Europe Armenia Meat Offline M 11/9/2015 781416594 12/23/2015 7390 421.89 364.69 3117767.10 2695059.10 422708.00
1328 Europe Denmark Clothes Offline H 5/9/2012 713357150 6/3/2012 7088 109.28 35.84 774576.64 254033.92 520542.72
1329 Europe Finland Clothes Online L 4/22/2014 906794202 5/11/2014 9410 109.28 35.84 1028324.80 337254.40 691070.40

1330 rows × 14 columns

Like

vendas_europa.filter(like='Order', axis=1)
Order Priority Order Date Order ID
0 C 9/12/2011 478051030
1 M 10/14/2013 919133651
2 C 8/13/2014 987410676
3 L 10/31/2010 672330081
4 L 9/28/2016 579463422
... ... ... ...
1325 M 1/14/2014 634033286
1326 L 4/14/2014 559183347
1327 M 11/9/2015 781416594
1328 H 5/9/2012 713357150
1329 L 4/22/2014 906794202

1330 rows × 3 columns

Por tipo de dado

# selecionar colunas numéricas:
colunas_numericas = vendas_europa.select_dtypes(include=['number'])
colunas_numericas
Order ID Units Sold Unit Price Unit Cost Total Revenue Total Cost Total Profit
0 478051030 4778 47.45 31.79 226716.10 151892.62 74823.48
1 919133651 927 109.28 35.84 101302.56 33223.68 68078.88
2 987410676 5616 205.70 117.11 1155211.20 657689.76 497521.44
3 672330081 6266 651.21 524.96 4080481.86 3289399.36 791082.50
4 579463422 4958 9.33 6.92 46258.14 34309.36 11948.78
... ... ... ... ... ... ... ...
1325 634033286 3394 81.73 56.67 277391.62 192337.98 85053.64
1326 559183347 3633 205.70 117.11 747308.10 425460.63 321847.47
1327 781416594 7390 421.89 364.69 3117767.10 2695059.10 422708.00
1328 713357150 7088 109.28 35.84 774576.64 254033.92 520542.72
1329 906794202 9410 109.28 35.84 1028324.80 337254.40 691070.40

1330 rows × 7 columns

# selecionar colunas categóricas:
colunas_categoricas = vendas_europa.select_dtypes(include=['object'])
colunas_categoricas
Region Country Item Type Sales Channel Order Priority Order Date Ship Date
0 Europe Czech Republic Beverages Offline C 9/12/2011 9/29/2011
1 Europe Bosnia and Herzegovina Clothes Online M 10/14/2013 11/4/2013
2 Europe Austria Cereal Offline C 8/13/2014 9/6/2014
3 Europe Bulgaria Office Supplies Online L 10/31/2010 11/29/2010
4 Europe Estonia Fruits Online L 9/28/2016 11/1/2016
... ... ... ... ... ... ... ...
1325 Europe Norway Personal Care Offline M 1/14/2014 1/15/2014
1326 Europe Ukraine Cereal Offline L 4/14/2014 5/21/2014
1327 Europe Armenia Meat Offline M 11/9/2015 12/23/2015
1328 Europe Denmark Clothes Offline H 5/9/2012 6/3/2012
1329 Europe Finland Clothes Online L 4/22/2014 5/11/2014

1330 rows × 7 columns

É possível, ainda, filtrar pelo tipo de dado em específico:

print( vendas_europa.select_dtypes('object').columns.tolist() )
print( vendas_europa.select_dtypes('float64').columns.tolist() )
['Region', 'Country', 'Item Type', 'Sales Channel', 'Order Priority', 'Order Date', 'Ship Date']
['Unit Price', 'Unit Cost', 'Total Revenue', 'Total Cost', 'Total Profit']