Importação de dados com módulo Pandas
By Ricardo Perdiz in Python AED Importar
June 19, 2024
Olá, pessoal,
Seguem postagens para performar uma análise exploratória de dados em Python.
Começarei com comandos básicos para importar dados e fazer uma checagem usando o módulo
pandas
da linguagem Python.
Neste tutorial, utilizo Python versão 3.10.14.
Além de um lembrete para mim, creio que pode ser útil a vocês.
Carregando módulos Python
Carreguemos a biblioteca Pandas e numpy.
Observem as versões carregadas de cada módulo, ao utilizarmos o comando __version__
.
import pandas as pd
pd.__version__
## '2.2.2'
import numpy as np
np.__version__
## '1.26.4'
Lendo dados
Utilizamos o método Pandas read_csv()
para ler os dados.
Aqui utilizaremos um conjunto de dados comumente utilizado em tutoriais de Python, chamado cars
.
Obteremos esse conjunto de dados no seguinte endereço:
https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data.
dad = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data", header = None)
print(dad)
## 0 1 2 3 4 5 ... 20 21 22 23 24 25
## 0 3 ? alfa-romero gas std two ... 9.0 111 5000 21 27 13495
## 1 3 ? alfa-romero gas std two ... 9.0 111 5000 21 27 16500
## 2 1 ? alfa-romero gas std two ... 9.0 154 5000 19 26 16500
## 3 2 164 audi gas std four ... 10.0 102 5500 24 30 13950
## 4 2 164 audi gas std four ... 8.0 115 5500 18 22 17450
## .. .. ... ... ... ... ... ... ... ... ... .. .. ...
## 200 -1 95 volvo gas std four ... 9.5 114 5400 23 28 16845
## 201 -1 95 volvo gas turbo four ... 8.7 160 5300 19 25 19045
## 202 -1 95 volvo gas std four ... 8.8 134 5500 18 23 21485
## 203 -1 95 volvo diesel turbo four ... 23.0 106 4800 26 27 22470
## 204 -1 95 volvo gas turbo four ... 9.5 114 5400 19 25 22625
##
## [205 rows x 26 columns]
Explorando os dados
Método .head(n)
para ver as n
linhas do topo da tabela.
dad.head(6)
## 0 1 2 3 4 5 ... 20 21 22 23 24 25
## 0 3 ? alfa-romero gas std two ... 9.0 111 5000 21 27 13495
## 1 3 ? alfa-romero gas std two ... 9.0 111 5000 21 27 16500
## 2 1 ? alfa-romero gas std two ... 9.0 154 5000 19 26 16500
## 3 2 164 audi gas std four ... 10.0 102 5500 24 30 13950
## 4 2 164 audi gas std four ... 8.0 115 5500 18 22 17450
## 5 2 ? audi gas std two ... 8.5 110 5500 19 25 15250
##
## [6 rows x 26 columns]
dad.head(10)
## 0 1 2 3 4 5 ... 20 21 22 23 24 25
## 0 3 ? alfa-romero gas std two ... 9.0 111 5000 21 27 13495
## 1 3 ? alfa-romero gas std two ... 9.0 111 5000 21 27 16500
## 2 1 ? alfa-romero gas std two ... 9.0 154 5000 19 26 16500
## 3 2 164 audi gas std four ... 10.0 102 5500 24 30 13950
## 4 2 164 audi gas std four ... 8.0 115 5500 18 22 17450
## 5 2 ? audi gas std two ... 8.5 110 5500 19 25 15250
## 6 1 158 audi gas std four ... 8.5 110 5500 19 25 17710
## 7 1 ? audi gas std four ... 8.5 110 5500 19 25 18920
## 8 1 158 audi gas turbo four ... 8.3 140 5500 17 20 23875
## 9 0 ? audi gas turbo two ... 7.0 160 5500 16 22 ?
##
## [10 rows x 26 columns]
Para ver as n
últimas linhas do fim da tabela, devemos usar o método .tail(n)
.
dad.tail(6)
## 0 1 2 3 4 5 ... 20 21 22 23 24 25
## 199 -1 74 volvo gas turbo four ... 7.5 162 5100 17 22 18950
## 200 -1 95 volvo gas std four ... 9.5 114 5400 23 28 16845
## 201 -1 95 volvo gas turbo four ... 8.7 160 5300 19 25 19045
## 202 -1 95 volvo gas std four ... 8.8 134 5500 18 23 21485
## 203 -1 95 volvo diesel turbo four ... 23.0 106 4800 26 27 22470
## 204 -1 95 volvo gas turbo four ... 9.5 114 5400 19 25 22625
##
## [6 rows x 26 columns]
Acrescentando nomes de colunas
Esse conjunto de dados não possui um cabeçalho.
Então, devemos adicioná-lo manualmente.
Colocamos os nomes de cada coluna em uma lista e depois atribuímos o objeto headers
às colunas de nossa tabela dad
.
headers = ["symboling", "normalized-losses", "make", "fuel-type", "aspiration", "num-of-doors", "body-style", "drive-wheels", "engine-location", "wheel-base", "length", "width", "height", "curb-weight", "engine-type", "num-of-cylinders", "engine-size", "fuel-system", "bore", "stroke", "compression-ratio", "horsepower", "peak-rpm", "city-mpg", "highway-mpg", "price"]
dad.columns = headers
dad.head(5)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 ? alfa-romero ... 21 27 13495
## 1 3 ? alfa-romero ... 21 27 16500
## 2 1 ? alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
##
## [5 rows x 26 columns]
Tipos de dados
Para ver os tipos de dados de cada coluna, usamos o método dtypes
.
dad.dtypes
## symboling int64
## normalized-losses object
## make object
## fuel-type object
## aspiration object
## num-of-doors object
## body-style object
## drive-wheels object
## engine-location object
## wheel-base float64
## length float64
## width float64
## height float64
## curb-weight int64
## engine-type object
## num-of-cylinders object
## engine-size int64
## fuel-system object
## bore object
## stroke object
## compression-ratio float64
## horsepower object
## peak-rpm object
## city-mpg int64
## highway-mpg int64
## price object
## dtype: object
Sumário estatístico
Para obter um sumário estatístico, utilizamos o método describe()
.
Por padrão, este método performa o sumário apenas sobre as colunas numéricas.
Caso desejamos incluir todas as colunas, incluindo as com texto, devemos usar o argumento include = "all"
.
dad.describe()
## symboling wheel-base ... city-mpg highway-mpg
## count 205.000000 205.000000 ... 205.000000 205.000000
## mean 0.834146 98.756585 ... 25.219512 30.751220
## std 1.245307 6.021776 ... 6.542142 6.886443
## min -2.000000 86.600000 ... 13.000000 16.000000
## 25% 0.000000 94.500000 ... 19.000000 25.000000
## 50% 1.000000 97.000000 ... 24.000000 30.000000
## 75% 2.000000 102.400000 ... 30.000000 34.000000
## max 3.000000 120.900000 ... 49.000000 54.000000
##
## [8 rows x 10 columns]
dad.describe(include = "all")
## symboling normalized-losses make ... city-mpg highway-mpg price
## count 205.000000 205 205 ... 205.000000 205.000000 205
## unique NaN 52 22 ... NaN NaN 187
## top NaN ? toyota ... NaN NaN ?
## freq NaN 41 32 ... NaN NaN 4
## mean 0.834146 NaN NaN ... 25.219512 30.751220 NaN
## std 1.245307 NaN NaN ... 6.542142 6.886443 NaN
## min -2.000000 NaN NaN ... 13.000000 16.000000 NaN
## 25% 0.000000 NaN NaN ... 19.000000 25.000000 NaN
## 50% 1.000000 NaN NaN ... 24.000000 30.000000 NaN
## 75% 2.000000 NaN NaN ... 30.000000 34.000000 NaN
## max 3.000000 NaN NaN ... 49.000000 54.000000 NaN
##
## [11 rows x 26 columns]
Contagem de valores categóricos
make_counts = dad["make"].value_counts().to_frame('contagem')
make_counts.index.name = "carros"
make_counts
## contagem
## carros
## toyota 32
## nissan 18
## mazda 17
## mitsubishi 13
## honda 13
## volkswagen 12
## subaru 12
## peugot 11
## volvo 11
## dodge 9
## mercedes-benz 8
## bmw 8
## audi 7
## plymouth 7
## saab 6
## porsche 5
## isuzu 4
## jaguar 3
## chevrolet 3
## alfa-romero 3
## renault 2
## mercury 1
Indexação de colunas e linhas
Seleção de colunas
Para acessar uma coluna, pega-se o objeto dad
e usa o nome da coluna entre [
para obter os dados.
Usando apenas um [
, obteremos uma Série (==“Series”).
Caso utilizemos dois [[
, teremos então um “DataFrame” do Pandas.
Vejam abaixo:
type(dad["price"])
## <class 'pandas.core.series.Series'>
dad["price"]
## 0 13495
## 1 16500
## 2 16500
## 3 13950
## 4 17450
## ...
## 200 16845
## 201 19045
## 202 21485
## 203 22470
## 204 22625
## Name: price, Length: 205, dtype: object
type(dad[["price"]])
## <class 'pandas.core.frame.DataFrame'>
dad[["price"]]
## price
## 0 13495
## 1 16500
## 2 16500
## 3 13950
## 4 17450
## .. ...
## 200 16845
## 201 19045
## 202 21485
## 203 22470
## 204 22625
##
## [205 rows x 1 columns]
dad[["symboling", "make"]]
## symboling make
## 0 3 alfa-romero
## 1 3 alfa-romero
## 2 1 alfa-romero
## 3 2 audi
## 4 2 audi
## .. ... ...
## 200 -1 volvo
## 201 -1 volvo
## 202 -1 volvo
## 203 -1 volvo
## 204 -1 volvo
##
## [205 rows x 2 columns]
dad[["height", "price", "bore"]]
## height price bore
## 0 48.8 13495 3.47
## 1 48.8 16500 3.47
## 2 52.4 16500 2.68
## 3 54.3 13950 3.19
## 4 54.3 17450 3.19
## .. ... ... ...
## 200 55.5 16845 3.78
## 201 55.5 19045 3.78
## 202 55.5 21485 3.58
## 203 55.5 22470 3.01
## 204 55.5 22625 3.78
##
## [205 rows x 3 columns]
Seleção de linhas
dad.iloc[[1]]
## symboling normalized-losses make ... city-mpg highway-mpg price
## 1 3 ? alfa-romero ... 21 27 16500
##
## [1 rows x 26 columns]
dad.iloc[[5]]
## symboling normalized-losses make ... city-mpg highway-mpg price
## 5 2 ? audi ... 19 25 15250
##
## [1 rows x 26 columns]
dad.iloc[[4,5]]
## symboling normalized-losses make ... city-mpg highway-mpg price
## 4 2 164 audi ... 18 22 17450
## 5 2 ? audi ... 19 25 15250
##
## [2 rows x 26 columns]
Seleção de colunas e linhas
dad.iloc[[1,2], 1]
## 1 ?
## 2 ?
## Name: normalized-losses, dtype: object
dad.loc[[1,2], 'normalized-losses']
## 1 ?
## 2 ?
## Name: normalized-losses, dtype: object
Substituição de valores
Para substituir valores, podemos utilizar o métodod replace()
, que funciona assim:
dados.replace("OqueQueremosSubstituir", "ValorParaColocarNoLugar")
dad.replace('?',np.NaN).head(20)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 NaN alfa-romero ... 21 27 13495
## 1 3 NaN alfa-romero ... 21 27 16500
## 2 1 NaN alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
## 5 2 NaN audi ... 19 25 15250
## 6 1 158 audi ... 19 25 17710
## 7 1 NaN audi ... 19 25 18920
## 8 1 158 audi ... 17 20 23875
## 9 0 NaN audi ... 16 22 NaN
## 10 2 192 bmw ... 23 29 16430
## 11 0 192 bmw ... 23 29 16925
## 12 0 188 bmw ... 21 28 20970
## 13 0 188 bmw ... 21 28 21105
## 14 1 NaN bmw ... 20 25 24565
## 15 0 NaN bmw ... 16 22 30760
## 16 0 NaN bmw ... 16 22 41315
## 17 0 NaN bmw ... 15 20 36880
## 18 2 121 chevrolet ... 47 53 5151
## 19 1 98 chevrolet ... 38 43 6295
##
## [20 rows x 26 columns]
Se executarmos o comando como apresentado, nada foi salvo. Vejam a coluna “price”, por exemplo:
dad.head(20)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 ? alfa-romero ... 21 27 13495
## 1 3 ? alfa-romero ... 21 27 16500
## 2 1 ? alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
## 5 2 ? audi ... 19 25 15250
## 6 1 158 audi ... 19 25 17710
## 7 1 ? audi ... 19 25 18920
## 8 1 158 audi ... 17 20 23875
## 9 0 ? audi ... 16 22 ?
## 10 2 192 bmw ... 23 29 16430
## 11 0 192 bmw ... 23 29 16925
## 12 0 188 bmw ... 21 28 20970
## 13 0 188 bmw ... 21 28 21105
## 14 1 ? bmw ... 20 25 24565
## 15 0 ? bmw ... 16 22 30760
## 16 0 ? bmw ... 16 22 41315
## 17 0 ? bmw ... 15 20 36880
## 18 2 121 chevrolet ... 47 53 5151
## 19 1 98 chevrolet ... 38 43 6295
##
## [20 rows x 26 columns]
Se quisermos fazer a alteração no próprio objeto, devemos utilizar o argumento inplace = True
.
dad.replace("?", np.NaN, inplace = True)
Checando as substituições.
dad.head(10)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 NaN alfa-romero ... 21 27 13495
## 1 3 NaN alfa-romero ... 21 27 16500
## 2 1 NaN alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
## 5 2 NaN audi ... 19 25 15250
## 6 1 158 audi ... 19 25 17710
## 7 1 NaN audi ... 19 25 18920
## 8 1 158 audi ... 17 20 23875
## 9 0 NaN audi ... 16 22 NaN
##
## [10 rows x 26 columns]
Removendo colunas com valores faltantes
Podemos usar o método dropna()
.
O argumento axis
controla o que eliminar: se 0, elimina linhas com valores faltantes; se 1, elimina colunas.
Veja abaixo que há um valor faltante na linha 9:
dad.head(20)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 NaN alfa-romero ... 21 27 13495
## 1 3 NaN alfa-romero ... 21 27 16500
## 2 1 NaN alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
## 5 2 NaN audi ... 19 25 15250
## 6 1 158 audi ... 19 25 17710
## 7 1 NaN audi ... 19 25 18920
## 8 1 158 audi ... 17 20 23875
## 9 0 NaN audi ... 16 22 NaN
## 10 2 192 bmw ... 23 29 16430
## 11 0 192 bmw ... 23 29 16925
## 12 0 188 bmw ... 21 28 20970
## 13 0 188 bmw ... 21 28 21105
## 14 1 NaN bmw ... 20 25 24565
## 15 0 NaN bmw ... 16 22 30760
## 16 0 NaN bmw ... 16 22 41315
## 17 0 NaN bmw ... 15 20 36880
## 18 2 121 chevrolet ... 47 53 5151
## 19 1 98 chevrolet ... 38 43 6295
##
## [20 rows x 26 columns]
Rodando o comando abaixo, essa linha será eliminada. Veja:
dad.dropna(subset = ["price"], axis = 0).head(20)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 NaN alfa-romero ... 21 27 13495
## 1 3 NaN alfa-romero ... 21 27 16500
## 2 1 NaN alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
## 5 2 NaN audi ... 19 25 15250
## 6 1 158 audi ... 19 25 17710
## 7 1 NaN audi ... 19 25 18920
## 8 1 158 audi ... 17 20 23875
## 10 2 192 bmw ... 23 29 16430
## 11 0 192 bmw ... 23 29 16925
## 12 0 188 bmw ... 21 28 20970
## 13 0 188 bmw ... 21 28 21105
## 14 1 NaN bmw ... 20 25 24565
## 15 0 NaN bmw ... 16 22 30760
## 16 0 NaN bmw ... 16 22 41315
## 17 0 NaN bmw ... 15 20 36880
## 18 2 121 chevrolet ... 47 53 5151
## 19 1 98 chevrolet ... 38 43 6295
## 20 0 81 chevrolet ... 38 43 6575
##
## [20 rows x 26 columns]
Se quisermos eliminar o valor faltante no próprio objeto, podemos utilizar novamente o argumento inplace = True
.
dad.dropna(subset = ["price"], axis = 0, inplace = True)
dad.head(20)
## symboling normalized-losses make ... city-mpg highway-mpg price
## 0 3 NaN alfa-romero ... 21 27 13495
## 1 3 NaN alfa-romero ... 21 27 16500
## 2 1 NaN alfa-romero ... 19 26 16500
## 3 2 164 audi ... 24 30 13950
## 4 2 164 audi ... 18 22 17450
## 5 2 NaN audi ... 19 25 15250
## 6 1 158 audi ... 19 25 17710
## 7 1 NaN audi ... 19 25 18920
## 8 1 158 audi ... 17 20 23875
## 10 2 192 bmw ... 23 29 16430
## 11 0 192 bmw ... 23 29 16925
## 12 0 188 bmw ... 21 28 20970
## 13 0 188 bmw ... 21 28 21105
## 14 1 NaN bmw ... 20 25 24565
## 15 0 NaN bmw ... 16 22 30760
## 16 0 NaN bmw ... 16 22 41315
## 17 0 NaN bmw ... 15 20 36880
## 18 2 121 chevrolet ... 47 53 5151
## 19 1 98 chevrolet ... 38 43 6295
## 20 0 81 chevrolet ... 38 43 6575
##
## [20 rows x 26 columns]
Nomes de colunas
Para checar nomes de colunas:
print(dad.columns)
## Index(['symboling', 'normalized-losses', 'make', 'fuel-type', 'aspiration',
## 'num-of-doors', 'body-style', 'drive-wheels', 'engine-location',
## 'wheel-base', 'length', 'width', 'height', 'curb-weight', 'engine-type',
## 'num-of-cylinders', 'engine-size', 'fuel-system', 'bore', 'stroke',
## 'compression-ratio', 'horsepower', 'peak-rpm', 'city-mpg',
## 'highway-mpg', 'price'],
## dtype='object')
Checagem de dados
Um sumário conciso dos dados pode ser obtido com o método info()
.
dad.info()
## <class 'pandas.core.frame.DataFrame'>
## Index: 201 entries, 0 to 204
## Data columns (total 26 columns):
## # Column Non-Null Count Dtype
## --- ------ -------------- -----
## 0 symboling 201 non-null int64
## 1 normalized-losses 164 non-null object
## 2 make 201 non-null object
## 3 fuel-type 201 non-null object
## 4 aspiration 201 non-null object
## 5 num-of-doors 199 non-null object
## 6 body-style 201 non-null object
## 7 drive-wheels 201 non-null object
## 8 engine-location 201 non-null object
## 9 wheel-base 201 non-null float64
## 10 length 201 non-null float64
## 11 width 201 non-null float64
## 12 height 201 non-null float64
## 13 curb-weight 201 non-null int64
## 14 engine-type 201 non-null object
## 15 num-of-cylinders 201 non-null object
## 16 engine-size 201 non-null int64
## 17 fuel-system 201 non-null object
## 18 bore 197 non-null object
## 19 stroke 197 non-null object
## 20 compression-ratio 201 non-null float64
## 21 horsepower 199 non-null object
## 22 peak-rpm 199 non-null object
## 23 city-mpg 201 non-null int64
## 24 highway-mpg 201 non-null int64
## 25 price 201 non-null object
## dtypes: float64(5), int64(5), object(16)
## memory usage: 42.4+ KB
Seleção de dados numéricos
Podemos selecionar apenas os dados numéricos:
dad_numerico = dad._get_numeric_data()
dad_numerico.head()
## symboling wheel-base length ... compression-ratio city-mpg highway-mpg
## 0 3 88.6 168.8 ... 9.0 21 27
## 1 3 88.6 168.8 ... 9.0 21 27
## 2 1 94.5 171.2 ... 9.0 19 26
## 3 2 99.8 176.6 ... 10.0 24 30
## 4 2 99.4 176.6 ... 8.0 18 22
##
## [5 rows x 10 columns]
Remoção de colunas
Podemos remover colunas com o método drop()
.
dad.drop(["symboling"], axis = 1).head()
## normalized-losses make fuel-type ... city-mpg highway-mpg price
## 0 NaN alfa-romero gas ... 21 27 13495
## 1 NaN alfa-romero gas ... 21 27 16500
## 2 NaN alfa-romero gas ... 19 26 16500
## 3 164 audi gas ... 24 30 13950
## 4 164 audi gas ... 18 22 17450
##
## [5 rows x 25 columns]
dad.drop(["make"], axis = 1).head()
## symboling normalized-losses fuel-type ... city-mpg highway-mpg price
## 0 3 NaN gas ... 21 27 13495
## 1 3 NaN gas ... 21 27 16500
## 2 1 NaN gas ... 19 26 16500
## 3 2 164 gas ... 24 30 13950
## 4 2 164 gas ... 18 22 17450
##
## [5 rows x 25 columns]
Salva arquivos em diferentes formatos
Os métodos to_csv()
e to_json()
salvam arquivos em formatos csv e json, respectivamente.
Utilizando o argumento index = False
em to_csv()
previne os nomes de linhas serem salvos no arquivo final.
dad.to_csv("autos.csv", index = False)
dad.to_json("autos.json")
Para salvar arquivos xlsx
, usei o módulo XlsxWriter
.
É necessário instalar o módulo antes de prosseguir.
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('autos.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
dad.to_excel(writer, sheet_name='Sheet1')
# Close the Pandas Excel writer and output the Excel file.
writer.close()
Para saber mais
Visitem o site do módulo pandas https://pandas.pydata.org/. Tem muita coisa por lá.
Bem, fico por aqui. Creio que isso pode ajudar alguém além de mim. Lembrando que o conteúdo apresentado aqui é super básico, tem muita coisa para explorar!
Até a próxima, pessoal! 💐🌴😎