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! 💐🌴😎