Gerenciamento de dados com Pandas

Gerenciamento de dados com Pandas Gerenciamento de dados com Pandas

Manipulação de dados com Pandaslink image 138

Aviso: Este post foi traduzido para o português usando um modelo de tradução automática. Por favor, me avise se encontrar algum erro.

1. Resumolink image 139

Vamos dar uma pequena introdução à biblioteca de manipulação e análise de dados Pandas. Com ela, poderemos manipular e processar dados tabulares que nos ajudará a operar com eles e obter informações de maneira muito valiosa.

No description has been provided for this image

2. O que é o Pandas?link image 140

Pandas é uma biblioteca de Python projetada para tornar o trabalho com dados relacionais ou rotulados fácil e intuitivo.

Pandas está projetado para muitos tipos diferentes de dados:

  • Dados tabulares com colunas de tipos heterogêneos, como em uma tabela SQL ou uma planilha do Excel
  • Dados de séries temporais ordenados e desordenados (não necessariamente de frequência fixa).
  • Dados matriciais arbitrários (homogêneos ou heterogêneos) com rótulos de linha e coluna
  • Qualquer outra forma de conjuntos de dados observacionais/estatísticos. Não é necessário rotular os dados em absoluto para colocá-los em uma estrutura de dados do Pandas.

As duas estruturas de dados principais do Pandas são as Series (unidimensionais) e os DataFrames (bidimensionais). O Pandas é construído sobre o NumPy e é destinado a se integrar bem em um ambiente computacional científico com muitas outras bibliotecas de terceiros.

Para os cientistas de dados, o trabalho com dados geralmente se divide em várias etapas: coletar e limpar dados, analisá-los/modelá-los e, em seguida, organizar os resultados da análise de uma forma adequada para plotá-los ou exibi-los em formato de tabela. pandas é a ferramenta ideal para todas essas tarefas.

Outra característica é que o pandas é rápido, muitos dos algoritmos de baixo nível foram construídos em C.

2.1. Pandas como pdlink image 141

Geralmente na hora de importar pandas costuma-se importar com o alias de pd

	
import pandas as pd
print(pd.__version__)
Copy
	
1.0.1

3. Estruturas de dados do Pandaslink image 142

Em Pandas existem dois tipos de estruturas de dados: as Series e os DataFrames

3.1. Sérieslink image 143

O tipo de dado Serie é uma matriz unidimensional rotulada capaz de conter qualquer tipo de dados (inteiros, strings, números de ponto flutuante, objetos Python, etc.). Ela é dividida em índices.

Para criar um tipo de dado Serie a forma mais comum é

serie = pd.Series(data, index=index)
      

Onde data pode ser:

  • Um dicionário
  • Uma lista ou tupla
  • Um ndarray do Numpy
  • Um valor escalar

Como um dos tipos de dados pode ser um ndarray do NumPy, importamos o NumPy para poder usá-lo

	
import numpy as np
Copy

3.1.1. Séries a partir de um dicionáriolink image 144

	
diccionario = {"b": 1, "a": 0, "c": 2}
serie = pd.Series(diccionario)
serie
Copy
	
b 1
a 0
c 2
dtype: int64

Se passar um índice, serão extraídos os valores dos dados correspondentes às tags do índice. Se não existirem, são criados como NaN (not a number).

	
diccionario = {"b": 1, "a": 0, "c": 2}
serie = pd.Series(diccionario, index=["b", "c", "d", "a"])
serie
Copy
	
b 1.0
c 2.0
d NaN
a 0.0
dtype: float64

3.1.2. Séries a partir de uma lista ou tuplalink image 145

Se os dados vêm de uma lista ou tupla e nenhum índice é passado, um será criado com valores [0, ..., len(dados)-1]

	
serie = pd.Series([1, 2, 3, 4])
serie
Copy
	
0 1
1 2
2 3
3 4
dtype: int64

Se um índice for passado, ele deve ter o mesmo comprimento que os dados

	
serie = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
serie
Copy
	
a 1
b 2
c 3
d 4
dtype: int64

3.1.3. Séries a partir de um ndarraylink image 146

Se os dados vêm de um ndarray e nenhum índice é passado, será criado um com valores [0, ..., len(data)-1].

	
serie = pd.Series(np.random.randn(5))
serie
Copy
	
0 1.267865
1 -0.877857
2 -0.138556
3 -0.132987
4 -0.827295
dtype: float64

Se um índice for passado, ele deve ter o mesmo comprimento que os dados

	
serie = pd.Series(np.random.randn(5), index=["a", "b", "c", "d", "e"])
serie
Copy
	
a -1.091828
b -0.584243
c 0.220398
d 1.248923
e 1.652351
dtype: float64

3.1.4. Séries a partir de um escalarlink image 147

Se a série for criada a partir de um escalar, ela será criada com um único item

	
serie = pd.Series(5.0)
serie
Copy
	
0 5.0
dtype: float64

Se quiser criar mais itens na série, é necessário passar o índice com o número de itens desejados, desta forma todos os itens terão o valor do escalar

	
serie = pd.Series(5.0, index=["a", "b", "c", "d", "e"])
serie
Copy
	
a 5.0
b 5.0
c 5.0
d 5.0
e 5.0
dtype: float64

3.1.5. Operações com Sérieslink image 148

Assim como com o Numpy, podemos realizar operações com todos os elementos de uma série, sem ter que fazer uma iteração para cada um deles.

	
serie = pd.Series(5.0, index=["a", "b", "c", "d", "e"])
print(f"serie:\n{serie}")
print(f"\nserie + serie =\n{serie + serie}")
Copy
	
serie:
a 5.0
b 5.0
c 5.0
d 5.0
e 5.0
dtype: float64
serie + serie =
a 10.0
b 10.0
c 10.0
d 10.0
e 10.0
dtype: float64
	
serie = pd.Series(5.0, index=["a", "b", "c", "d", "e"])
print(f"serie:\n{serie}")
print(f"\nexp(serie) =\n{np.exp(serie)}")
Copy
	
serie:
a 5.0
b 5.0
c 5.0
d 5.0
e 5.0
dtype: float64
exp(serie) =
a 148.413159
b 148.413159
c 148.413159
d 148.413159
e 148.413159
dtype: float64

Uma diferença entre Series e ndarrays é que as operações entre Series alinham automaticamente os dados de acordo com suas etiquetas. Portanto, cálculos podem ser escritos sem considerar se as Series envolvidas têm as mesmas etiquetas. Se uma etiqueta não for encontrada em uma Serie ou outra, o resultado será marcado como faltante (NaN).

	
serie = pd.Series(5.0, index=["a", "b", "c", "d", "e"])
print(f"serie:\n{serie}")
print(f"\nserie[1:] + serie[:-1] =\n{serie[1:] + serie[:-1]}")
Copy
	
serie:
a 5.0
b 5.0
c 5.0
d 5.0
e 5.0
dtype: float64
serie[1:] + serie[:-1] =
a NaN
b 10.0
c 10.0
d 10.0
e NaN
dtype: float64

3.1.6. Atributo nome das Sérieslink image 149

Um dos atributos das Series é name, o qual corresponde ao nome que terão quando forem adicionadas a um DataFrame. No sentido contrário, quando se obtém uma série de um DataFrame, essa série terá como nome o que tinha no DataFrame.

	
serie = pd.Series(np.random.randn(5), name="aleatorio")
serie
Copy
	
0 -0.191009
1 -0.793151
2 -0.907747
3 -1.440508
4 -0.676419
Name: aleatorio, dtype: float64

Pode-se alterar o nome de uma série por meio do método rename()

	
serie = serie.rename("random")
serie
Copy
	
0 -0.191009
1 -0.793151
2 -0.907747
3 -1.440508
4 -0.676419
Name: random, dtype: float64

3.2. DataFrameslink image 150

Um DataFrame é uma estrutura de dados rotulada e bidimensional, com colunas de tipos potencialmente diferentes, ou seja, em uma coluna pode haver dados do tipo inteiro, em outra coluna dados do tipo string, etc. Pode pensar nisso como uma planilha ou uma tabela SQL, ou um dicionário de objetos Series.

É o objeto pandas mais utilizado. Assim como as Series, os DataFrames aceitam muitos tipos diferentes de entrada:

Junto com os dados, opcionalmente você pode passar argumentos de índice (rótulos de linha) e colunas (rótulos de coluna). Se você passar um índice e/ou colunas, está garantindo o índice e/ou colunas do DataFrame resultante. Portanto, um dicionário de Series mais um índice específico descartará todos os dados que não coincidam com o índice passado

Se não forem passadas as etiquetas dos eixos, elas serão construídas a partir dos dados de entrada com base em regras de bom senso.

3.2.1. DataFrames a partir de um dicionário de Serieslink image 151

Se um dicionário com Series for passado, o DataFrame será criado com tantas colunas quantas Series o dicionário possuir.

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0]),
          "dos": pd.Series([4.0, 5.0, 6.0, 7.0])
          }
      
      dataframe = pd.DataFrame(diccionario)
      dataframe
      
Out[87]:
uno dos
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
3 NaN 7.0

Se cada uma das Series tiver índices definidos, o DataFrame resultante será a união desses índices.

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0], index=["a", "b", "c"]),
          "dos": pd.Series([4.0, 5.0, 6.0, 7.0], index=["a", "b", "c", "d"])
          }
      
      dataframe = pd.DataFrame(diccionario)
      dataframe
      
Out[88]:
uno dos
a 1.0 4.0
b 2.0 5.0
c 3.0 6.0
d NaN 7.0
dataframe = pd.DataFrame(diccionario, index=["d", "b", "a"])
      dataframe
      
Out[89]:
uno dos
d NaN 7.0
b 2.0 5.0
a 1.0 4.0

Se as colunas forem passadas, elas aparecerão na ordem passada.

dataframe = pd.DataFrame(diccionario, columns=["dos", "tres"])
      dataframe
      
Out[90]:
dos tres
a 4.0 NaN
b 5.0 NaN
c 6.0 NaN
d 7.0 NaN

3.2.2. DataFrames a partir de um dicionário de ndarrays ou listaslink image 152

Todos os ndarrays ou listas devem ter o mesmo comprimento. Se um índice for passado, também deve ter o mesmo comprimento que os ndarrays ou listas.

diccionario = {
          "uno": [1.0, 2.0, 3.0, 4.0],
          "dos": [4.0, 3.0, 2.0, 1.0]
          }
      
      dataframe = pd.DataFrame(diccionario)
      dataframe
      
Out[91]:
uno dos
0 1.0 4.0
1 2.0 3.0
2 3.0 2.0
3 4.0 1.0

3.2.3. DataFrames a partir de uma matrizlink image 153

Se um índice for passado, ele deve ter o mesmo comprimento que o número de linhas da matriz e, se forem passadas as colunas, elas devem ter o mesmo comprimento que as colunas da matriz.

matriz = np.array([[1, 3], [2, 2], [3, 1]])
      
      dataframe = pd.DataFrame(matriz, index=["a", "b", "c"], columns=["columna1", "columna2"])
      dataframe
      
Out[92]:
columna1 columna2
a 1 3
b 2 2
c 3 1

3.2.4. DataFrames a partir de uma lista de dicionárioslink image 154

lista = [{"a": 1, "b": 2}, {"a": 5, "b": 10, "c": 20}]
      
      dataframe = pd.DataFrame(lista)
      dataframe
      
Out[93]:
a b c
0 1 2 NaN
1 5 10 20.0

3.2.5. DataFrames a partir de um dicionário de tuplaslink image 155

diccionario = {
          ("a", "b"): {("A", "B"): 1, ("A", "C"): 2},
          ("a", "a"): {("A", "C"): 3, ("A", "B"): 4},
          ("a", "c"): {("A", "B"): 5, ("A", "C"): 6},
          ("b", "a"): {("A", "C"): 7, ("A", "B"): 8},
          ("b", "b"): {("A", "D"): 9, ("A", "B"): 10},
          }
      
      dataframe = pd.DataFrame(diccionario)
      dataframe
      
Out[94]:
a b
b a c a b
A B 1.0 4.0 5.0 8.0 10.0
C 2.0 3.0 6.0 7.0 NaN
D NaN NaN NaN NaN 9.0

3.2.6. DataFrames a partir de uma Sérielink image 156

O resultado será um DataFrame com o mesmo índice que a Série de entrada, e com uma coluna cujo nome é o nome original da Série (apenas se não for fornecido outro nome de coluna).

diccionario = {"b": 1, "a": 0, "c": 2}
      
      serie = pd.Series(diccionario)
      
      dataframe = pd.DataFrame(serie)
      dataframe
      
Out[95]:
0
b 1
a 0
c 2

4. Exploração de um DataFramelink image 157

Quando um DataFrame é muito grande, não pode ser representado inteiro

california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
      california_housing_train
      
Out[102]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0
... ... ... ... ... ... ... ... ... ...
16995 -124.26 40.58 52.0 2217.0 394.0 907.0 369.0 2.3571 111400.0
16996 -124.27 40.69 36.0 2349.0 528.0 1194.0 465.0 2.5179 79000.0
16997 -124.30 41.84 17.0 2677.0 531.0 1244.0 456.0 3.0313 103600.0
16998 -124.30 41.80 19.0 2672.0 552.0 1298.0 478.0 1.9797 85800.0
16999 -124.35 40.54 52.0 1820.0 300.0 806.0 270.0 3.0147 94600.0

17000 rows × 9 columns

Portanto, é muito útil ter métodos para explorá-lo e obter informações de maneira rápida.

4.1. Cabeça do DataFramelink image 158

Para ver as primeiras linhas e ter uma ideia de como é o DataFrame existe o método head(), que por padrão mostra as primeiras 5 linhas do DataFrame. Se quiser ver um número diferente de linhas, introduzi-lo através do atributo n

california_housing_train.head(n=10)
      
Out[103]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0
5 -114.58 33.63 29.0 1387.0 236.0 671.0 239.0 3.3438 74000.0
6 -114.58 33.61 25.0 2907.0 680.0 1841.0 633.0 2.6768 82400.0
7 -114.59 34.83 41.0 812.0 168.0 375.0 158.0 1.7083 48500.0
8 -114.59 33.61 34.0 4789.0 1175.0 3134.0 1056.0 2.1782 58400.0
9 -114.60 34.83 46.0 1497.0 309.0 787.0 271.0 2.1908 48100.0

4.2. Cauda do DataFramelink image 159

Se o que se quer for visualizar as últimas linhas, pode-se usar o método tail(), através do parâmetro n escolhe-se quantas linhas exibir.

california_housing_train.tail()
      
Out[104]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
16995 -124.26 40.58 52.0 2217.0 394.0 907.0 369.0 2.3571 111400.0
16996 -124.27 40.69 36.0 2349.0 528.0 1194.0 465.0 2.5179 79000.0
16997 -124.30 41.84 17.0 2677.0 531.0 1244.0 456.0 3.0313 103600.0
16998 -124.30 41.80 19.0 2672.0 552.0 1298.0 478.0 1.9797 85800.0
16999 -124.35 40.54 52.0 1820.0 300.0 806.0 270.0 3.0147 94600.0

4.3. Informação do DataFramelink image 160

Outro método muito útil é info() que nos dá informações sobre o DataFrame

	
california_housing_train.info()
Copy
	
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 17000 entries, 0 to 16999
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 longitude 17000 non-null float64
1 latitude 17000 non-null float64
2 housing_median_age 17000 non-null float64
3 total_rooms 17000 non-null float64
4 total_bedrooms 17000 non-null float64
5 population 17000 non-null float64
6 households 17000 non-null float64
7 median_income 17000 non-null float64
8 median_house_value 17000 non-null float64
dtypes: float64(9)
memory usage: 1.2 MB

4.4. Linhas e Colunas do DataFramelink image 161

Os índices e as colunas de um DataFrame podem ser obtidos através dos métodos index e columns

	
diccionario = {
"uno": pd.Series([1.0, 2.0, 3.0], index=["a", "b", "c"]),
"dos": pd.Series([4.0, 5.0, 6.0, 7.0], index=["a", "b", "c", "d"])
}
dataframe = pd.DataFrame(diccionario)
indices = dataframe.index
columnas = dataframe.columns
print(f"El DataFrame tiene los índices\n {indices}\n")
print(f"El DataFrame tiene las columnas\n {columnas}")
Copy
	
El DataFrame tiene los índices
Index(['a', 'b', 'c', 'd'], dtype='object')
El DataFrame tiene las columnas
Index(['uno', 'dos'], dtype='object')

4.5. Descrição do DataFramelink image 162

O método describe() mostra um resumo estatístico rápido dos dados do DataFrame

california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
      california_housing_train.describe()
      
Out[107]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
count 17000.000000 17000.000000 17000.000000 17000.000000 17000.000000 17000.000000 17000.000000 17000.000000 17000.000000
mean -119.562108 35.625225 28.589353 2643.664412 539.410824 1429.573941 501.221941 3.883578 207300.912353
std 2.005166 2.137340 12.586937 2179.947071 421.499452 1147.852959 384.520841 1.908157 115983.764387
min -124.350000 32.540000 1.000000 2.000000 1.000000 3.000000 1.000000 0.499900 14999.000000
25% -121.790000 33.930000 18.000000 1462.000000 297.000000 790.000000 282.000000 2.566375 119400.000000
50% -118.490000 34.250000 29.000000 2127.000000 434.000000 1167.000000 409.000000 3.544600 180400.000000
75% -118.000000 37.720000 37.000000 3151.250000 648.250000 1721.000000 605.250000 4.767000 265000.000000
max -114.310000 41.950000 52.000000 37937.000000 6445.000000 35682.000000 6082.000000 15.000100 500001.000000

4.6. Ordenação do DataFramelink image 163

As linhas de um DataFrame podem ser ordenadas alfabeticamente através do método sort_index().

california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
      california_housing_train.sort_index().head()
      
Out[108]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0

Como neste caso as linhas já estavam ordenadas, definimos ascending=False para que a ordem seja inversa.

california_housing_train.sort_index(ascending=False).head()
      
Out[109]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
16999 -124.35 40.54 52.0 1820.0 300.0 806.0 270.0 3.0147 94600.0
16998 -124.30 41.80 19.0 2672.0 552.0 1298.0 478.0 1.9797 85800.0
16997 -124.30 41.84 17.0 2677.0 531.0 1244.0 456.0 3.0313 103600.0
16996 -124.27 40.69 36.0 2349.0 528.0 1194.0 465.0 2.5179 79000.0
16995 -124.26 40.58 52.0 2217.0 394.0 907.0 369.0 2.3571 111400.0

Se axis=1 deve ser inserido quando o objetivo é ordenar as colunas, pois por padrão é 0.

california_housing_train.sort_index(axis=1).head()
      
Out[110]:
households housing_median_age latitude longitude median_house_value median_income population total_bedrooms total_rooms
0 472.0 15.0 34.19 -114.31 66900.0 1.4936 1015.0 1283.0 5612.0
1 463.0 19.0 34.40 -114.47 80100.0 1.8200 1129.0 1901.0 7650.0
2 117.0 17.0 33.69 -114.56 85700.0 1.6509 333.0 174.0 720.0
3 226.0 14.0 33.64 -114.57 73400.0 3.1917 515.0 337.0 1501.0
4 262.0 20.0 33.57 -114.57 65500.0 1.9250 624.0 326.0 1454.0

Se quisermos ordenar o DataFrame através de uma coluna específica, temos que usar o método sort_values() e indicar a label da coluna pela qual queremos ordenar.

california_housing_train.sort_values('median_house_value')
      
Out[111]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
568 -117.02 36.40 19.0 619.0 239.0 490.0 164.0 2.1000 14999.0
16643 -122.74 39.71 16.0 255.0 73.0 85.0 38.0 1.6607 14999.0
16801 -123.17 40.31 36.0 98.0 28.0 18.0 8.0 0.5360 14999.0
3226 -117.86 34.24 52.0 803.0 267.0 628.0 225.0 4.1932 14999.0
7182 -118.33 34.15 39.0 493.0 168.0 259.0 138.0 2.3667 17500.0
... ... ... ... ... ... ... ... ... ...
15834 -122.42 37.81 52.0 1314.0 317.0 473.0 250.0 4.3472 500001.0
7927 -118.40 33.87 38.0 2398.0 431.0 911.0 392.0 5.2319 500001.0
3546 -117.90 33.63 28.0 2370.0 352.0 832.0 347.0 7.1148 500001.0
7924 -118.40 33.88 35.0 1060.0 191.0 444.0 196.0 8.0015 500001.0
14011 -122.04 37.26 24.0 4973.0 709.0 1692.0 696.0 7.8627 500001.0

17000 rows × 9 columns

4.7. Estatísticas do DataFramelink image 164

Estatísticas do DataFrame podem ser obtidas, como a média, a moda e o desvio padrão.

	
california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
print(f"media:\n{california_housing_train.mean()}")
print(f"\n\ndesviación estandar:\n{california_housing_train.std()}")
Copy
	
media:
longitude -119.562108
latitude 35.625225
housing_median_age 28.589353
total_rooms 2643.664412
total_bedrooms 539.410824
population 1429.573941
households 501.221941
median_income 3.883578
median_house_value 207300.912353
dtype: float64
desviación estandar:
longitude 2.005166
latitude 2.137340
housing_median_age 12.586937
total_rooms 2179.947071
total_bedrooms 421.499452
population 1147.852959
households 384.520841
median_income 1.908157
median_house_value 115983.764387
dtype: float64

Se querem obter as estatísticas sobre as linhas e não sobre as colunas, é necessário indicá-lo através de axis=1

	
california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
print(f"media:\n{california_housing_train.mean(axis=1)}")
print(f"\n\ndesviación estandar:\n{california_housing_train.std(axis=1)}")
Copy
	
media:
0 8357.597067
1 10131.527778
2 9664.642322
3 8435.029078
4 7567.436111
...
16995 12806.408567
16996 9276.770878
16997 12049.507922
16998 10082.053300
16999 10863.022744
Length: 17000, dtype: float64
desviación estandar:
0 22026.612445
1 26352.939272
2 28514.316588
3 24366.754747
4 21730.014569
...
16995 36979.676899
16996 26158.006771
16997 34342.876792
16998 28408.152329
16999 31407.119788
Length: 17000, dtype: float64

Outra coisa útil que se pode obter dos DataFrames é, por exemplo, o número de vezes que cada item de uma coluna se repete.

	
california_housing_train["total_rooms"].value_counts()
Copy
	
1582.0 16
1527.0 15
1717.0 14
1471.0 14
1703.0 14
..
157.0 1
2760.0 1
458.0 1
10239.0 1
4068.0 1
Name: total_rooms, Length: 5533, dtype: int64

Por exemplo, podemos ver que há um total de 16 casas com 1582 quartos.

4.8. Memória usadalink image 165

Podemos ver a memória que o DataFrame utiliza

	
california_housing_train.memory_usage(deep=True)
Copy
	
Index 128
longitude 136000
latitude 136000
housing_median_age 136000
total_rooms 136000
total_bedrooms 136000
population 136000
households 136000
median_income 136000
median_house_value 136000
dtype: int64

5. Adição de dadoslink image 166

5.1. Adição de colunaslink image 167

Colunas podem ser adicionadas facilmente como operações de outras colunas

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0]),
          "dos": pd.Series([4.0, 5.0, 6.0, 7.0])
          }
      
      dataframe = pd.DataFrame(diccionario)
      
      dataframe["tres"] = dataframe["uno"] + dataframe["dos"]
      dataframe["flag"] = dataframe["tres"] > 7.0
      
      dataframe
      
Out[ ]:
uno dos tres flag
0 1.0 4.0 5.0 False
1 2.0 5.0 7.0 False
2 3.0 6.0 9.0 True
3 NaN 7.0 NaN False

Também é possível adicionar colunas indicando qual valor todos os seus itens terão

dataframe["constante"] = 8.0
      dataframe
      
Out[ ]:
uno dos tres flag constante
0 1.0 4.0 5.0 False 8.0
1 2.0 5.0 7.0 False 8.0
2 3.0 6.0 9.0 True 8.0
3 NaN 7.0 NaN False 8.0

Se uma Serie for adicionada e não tiver o mesmo número de índices que o DataFrame, ela será ajustada ao número de índices do DataFrame.

dataframe["Menos indices"] = dataframe["uno"][:2]
      dataframe
      
Out[ ]:
uno dos tres flag constante Menos indices
0 1.0 4.0 5.0 False 8.0 1.0
1 2.0 5.0 7.0 False 8.0 2.0
2 3.0 6.0 9.0 True 8.0 NaN
3 NaN 7.0 NaN False 8.0 NaN

Com os métodos anteriores a coluna era adicionada no final, mas se quiser adicionar a coluna em uma posição específica, pode-se utilizar o método insert().

Por exemplo, se quiser adicionar uma coluna na posição 3 (considerando que a contagem começa na posição 0), que o nome da coluna seja coluna inserida e que seu valor seja o dobro do da coluna tres, faria-se da seguinte maneira

dataframe.insert(loc=3, column="columna insertada", value=dataframe["tres"]*2)
      dataframe
      
Out[ ]:
uno dos tres columna insertada flag constante Menos indices
0 1.0 4.0 5.0 10.0 False 8.0 1.0
1 2.0 5.0 7.0 14.0 False 8.0 2.0
2 3.0 6.0 9.0 18.0 True 8.0 NaN
3 NaN 7.0 NaN NaN False 8.0 NaN

Se quiser adicionar mais de uma coluna por comando, pode-se usar o método assign()

dataframe = dataframe.assign(
          columna_asignada1 = dataframe["uno"] * dataframe["tres"],
          columna_asignada2 = dataframe["dos"] * dataframe["tres"],
          )
      dataframe
      
Out[ ]:
uno dos tres columna insertada flag constante Menos indices columna_asignada1 columna_asignada2
0 1.0 4.0 5.0 10.0 False 8.0 1.0 5.0 20.0
1 2.0 5.0 7.0 14.0 False 8.0 2.0 14.0 35.0
2 3.0 6.0 9.0 18.0 True 8.0 NaN 27.0 54.0
3 NaN 7.0 NaN NaN False 8.0 NaN NaN NaN

5.2. Adição de linhaslink image 168

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0]),
          "dos": pd.Series([4.0, 5.0, 6.0, 7.0])
          }
      
      dataframe = pd.DataFrame(diccionario)
      
      dataframe.head()
      
Out[20]:
uno dos
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
3 NaN 7.0

Podemos adicionar uma linha no final com o método concat (que veremos com mais detalhes depois)

diccionario = {
          "uno": [10.0],
          "dos": [20.0]
          }
      
      dataframe = pd.concat([dataframe, pd.DataFrame(diccionario)])
      dataframe
      
Out[21]:
uno dos
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
3 NaN 7.0
0 10.0 20.0

Vemos que a coluna foi adicionada no final, mas possui o índice zero, então reorganizamos os índices através do método reset_index(drop=True)

dataframe = dataframe.reset_index(drop=True)
      dataframe
      
Out[23]:
index uno dos
0 0 1.0 4.0
1 1 2.0 5.0
2 2 3.0 6.0
3 3 NaN 7.0
4 0 10.0 20.0

6. Eliminaçao de dadoslink image 169

6.1. Eliminação de colunaslink image 170

Pode-se eliminar uma coluna específica utilizando o método pop()

dataframe.pop("constante")
      dataframe
      
Out[ ]:
uno dos tres columna insertada flag Menos indices columna_asignada1 columna_asignada2
0 1.0 4.0 5.0 10.0 False 1.0 5.0 20.0
1 2.0 5.0 7.0 14.0 False 2.0 14.0 35.0
2 3.0 6.0 9.0 18.0 True NaN 27.0 54.0
3 NaN 7.0 NaN NaN False NaN NaN NaN

O mediante del

del dataframe["flag"]
      dataframe
      
Out[ ]:
uno dos tres columna insertada Menos indices columna_asignada1 columna_asignada2
0 1.0 4.0 5.0 10.0 1.0 5.0 20.0
1 2.0 5.0 7.0 14.0 2.0 14.0 35.0
2 3.0 6.0 9.0 18.0 NaN 27.0 54.0
3 NaN 7.0 NaN NaN NaN NaN NaN

6.1. Eliminação de linhaslink image 171

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]),
          "dos": pd.Series([11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]),
          "tres": pd.Series([21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0])
          }
      
      dataframe = pd.DataFrame(diccionario)
      
      dataframe.head()
      
Out[49]:
uno dos tres
0 1.0 11.0 21.0
1 2.0 12.0 22.0
2 3.0 13.0 23.0
3 4.0 14.0 24.0
4 5.0 15.0 25.0

Se quisermos remover uma linha, podemos usar o método drop, especificando sua posição. Por exemplo, se quisermos remover a linha da posição 1

dataframe = dataframe.drop(1)
      dataframe
      
Out[50]:
uno dos tres
0 1.0 11.0 21.0
2 3.0 13.0 23.0
3 4.0 14.0 24.0
4 5.0 15.0 25.0
5 6.0 16.0 26.0
6 7.0 17.0 27.0
7 8.0 18.0 28.0
8 9.0 19.0 29.0
9 10.0 20.0 30.0

Se quisermos eliminar a última linha

dataframe = dataframe.drop(len(dataframe)-1)
      dataframe
      
Out[51]:
uno dos tres
0 1.0 11.0 21.0
2 3.0 13.0 23.0
3 4.0 14.0 24.0
4 5.0 15.0 25.0
5 6.0 16.0 26.0
6 7.0 17.0 27.0
7 8.0 18.0 28.0
9 10.0 20.0 30.0

Se quisermos remover um intervalo de linhas

dataframe = dataframe.drop(range(2, 5))
      dataframe
      
Out[52]:
uno dos tres
0 1.0 11.0 21.0
5 6.0 16.0 26.0
6 7.0 17.0 27.0
7 8.0 18.0 28.0
9 10.0 20.0 30.0

Se quisermos remover um conjunto de linhas determinado

dataframe = dataframe.drop([5, 7, 9])
      dataframe
      
Out[53]:
uno dos tres
0 1.0 11.0 21.0
6 7.0 17.0 27.0

Assim como quando adicionamos linhas, vemos que alguns índices foram removidos, então reorganizamos os índices usando o método reset_index(drop=True)

dataframe = dataframe.reset_index(drop=True)
      dataframe
      
Out[54]:
uno dos tres
0 1.0 11.0 21.0
1 7.0 17.0 27.0

7. Operações sobre DataFrameslink image 172

Operações podem ser realizadas em DataFrames da mesma forma que podem ser feitas com Numpy.

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]),
          "dos": pd.Series([11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]),
          "tres": pd.Series([21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0])
          }
      
      dataframe = pd.DataFrame(diccionario)
      
      dataframe.head()
      
Out[58]:
uno dos tres
0 1.0 11.0 21.0
1 2.0 12.0 22.0
2 3.0 13.0 23.0
3 4.0 14.0 24.0
4 5.0 15.0 25.0
dataframe[ ["uno", "dos", "tres"] ] * 2
      
Out[59]:
uno dos tres
0 2.0 22.0 42.0
1 4.0 24.0 44.0
2 6.0 26.0 46.0
3 8.0 28.0 48.0
4 10.0 30.0 50.0
5 12.0 32.0 52.0
6 14.0 34.0 54.0
7 16.0 36.0 56.0
8 18.0 38.0 58.0
9 20.0 40.0 60.0
np.exp(dataframe[ ["uno", "dos", "tres"] ])
      
Out[60]:
uno dos tres
0 2.718282 5.987414e+04 1.318816e+09
1 7.389056 1.627548e+05 3.584913e+09
2 20.085537 4.424134e+05 9.744803e+09
3 54.598150 1.202604e+06 2.648912e+10
4 148.413159 3.269017e+06 7.200490e+10
5 403.428793 8.886111e+06 1.957296e+11
6 1096.633158 2.415495e+07 5.320482e+11
7 2980.957987 6.565997e+07 1.446257e+12
8 8103.083928 1.784823e+08 3.931334e+12
9 22026.465795 4.851652e+08 1.068647e+13

Se quiser realizar operações mais complexas, pode-se usar o método apply().

	
dataframe = dataframe.apply(lambda x: x.max() - x.min())
dataframe
Copy
	
uno 9.0
dos 9.0
tres 9.0
dtype: float64

Foi aplicada uma função lambda porque é uma função simples, mas em caso de querer aplicar funções mais complexas, podemos defini-las e aplicá-las.

	
def funcion(x):
if x < 10:
return np.exp(x) - np.log(5*x) + np.sqrt(x)
elif x < 20:
return np.sin(x) + np.cos(x) + np.tan(x)
else:
return np.log(x) + np.log10(x) + np.log2(x)
dataframe = dataframe.apply(funcion)
dataframe
Copy
	
uno 8102.277265
dos 8102.277265
tres 8102.277265
dtype: float64

Utilizar o método apply em um DataFrame é muito mais rápido que fazer um for para cada uma das linhas e realizar a operação.

california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
      california_housing_train.head()
      
Out[64]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0

Vamos a calcular o percentual de quartos em relação ao total de cômodos

california_housing_train["percent_bedrooms"] = None
      %time california_housing_train["percent_bedrooms"] = california_housing_train.apply(lambda x: x["total_bedrooms"] / x["total_rooms"], axis=1)
      california_housing_train.head()
      
CPU times: user 309 ms, sys: 86 µs, total: 309 ms
      Wall time: 309 ms
      
Out[74]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value percent_bedrooms
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0 0.228617
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0 0.248497
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0 0.241667
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0 0.224517
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0 0.224209
california_housing_train["percent_bedrooms"] = None
      %time for i in range(len(california_housing_train)): california_housing_train["percent_bedrooms"][i] = california_housing_train["total_bedrooms"][i] / california_housing_train["total_rooms"][i]
      california_housing_train.head()
      
/home/wallabot/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: 
      A value is trying to be set on a copy of a slice from a DataFrame
      
      See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
        """Entry point for launching an IPython kernel.
      
CPU times: user 1.72 s, sys: 12 ms, total: 1.73 s
      Wall time: 1.72 s
      
Out[77]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value percent_bedrooms
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0 0.228617
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0 0.248497
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0 0.241667
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0 0.224517
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0 0.224209

Com a função lambda levou cerca de 300 ms, enquanto o loop for levou mais de 1 segundo.

8. Transpostalink image 173

Pode-se fazer a transposta de um DataFrame através do método T

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0], index=["fila a", "fila b", "fila c"]),
          "dos": pd.Series([4.0, 5.0, 6.0], index=["fila a", "fila b", "fila c"])
          }
      
      dataframe = pd.DataFrame(diccionario)
      
      dataframe["tres"] = dataframe["uno"] + dataframe["dos"]
      dataframe["flag"] = dataframe["tres"] > 7.0
      
      dataframe.T
      
Out[ ]:
fila a fila b fila c
uno 1 2 3
dos 4 5 6
tres 5 7 9
flag False False True

9. Conversão para Numpylink image 174

Se quiser converter uma Serie ou DataFrame para NumPy, pode-se usar o método to_numpy() ou a função np.asarray().

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0], index=["fila a", "fila b", "fila c"]),
          "dos": pd.Series([4.0, 5.0, 6.0], index=["fila a", "fila b", "fila c"])
          }
      
      dataframe = pd.DataFrame(diccionario)
      
      dataframe["tres"] = dataframe["uno"] + dataframe["dos"]
      dataframe["flag"] = dataframe["tres"] > 7.0
      
      dataframe
      
Out[ ]:
uno dos tres flag
fila a 1.0 4.0 5.0 False
fila b 2.0 5.0 7.0 False
fila c 3.0 6.0 9.0 True
	
matriz_np = dataframe.to_numpy()
matriz_np
Copy
	
array([[1.0, 4.0, 5.0, False],
[2.0, 5.0, 7.0, False],
[3.0, 6.0, 9.0, True]], dtype=object)
	
matriz_np = np.asarray(dataframe)
matriz_np
Copy
	
array([[1.0, 4.0, 5.0, False],
[2.0, 5.0, 7.0, False],
[3.0, 6.0, 9.0, True]], dtype=object)

Este exemplo não é o mais adequado, pois mistura números com booleanos, e como já explicamos no post anterior Cálculo matricial com NumPy, todos os elementos de um ndarray devem ser do mesmo tipo.

Neste caso, estamos misturando números com booleanos, então para resolver isso, o NumPy os converte todos para objetos.

Para resolver isso, ficamos apenas com os números e os convertemos para um ndarray.

	
matriz_np = dataframe[ ["uno", "dos", "tres"] ].to_numpy()
matriz_np, matriz_np.dtype
Copy
	
(array([[1., 4., 5.],
[2., 5., 7.],
[3., 6., 9.]]), dtype('float64'))

Agora pode-se ver que foi criado um ndarray onde todos os dados são do tipo float.

10. Leitura de dados de fontes externaslink image 175

Uma das maiores forças do Pandas é poder ler dados de arquivos, portanto não é necessário criar um DataFrame com os dados que se quer processar, mas sim ler esses dados de um arquivo.

Da mesma forma que é possível criar DataFrames a partir de arquivos externos, também é possível salvar DataFrames em arquivos, para assim criar o seu próprio conjunto de dados, configurá-lo da maneira que desejar e salvá-lo em um arquivo para poder usá-lo posteriormente.

Na tabela a seguir, são mostradas as funções para ler e escrever arquivos em diferentes formatos.

Formato Tipo de arquivo Função de leitura Função de escrita
texto CSV read_csv to_csv
texto Arquivo de texto de largura fixa read_fwf
texto JSON read_json to_json
texto HTML read_html to_html
texto Clipboard local read_clipboard to_clipboard
binário MS Excel read_excel to_excel
binário OpenDocument read_excel
binário Formato HDF5 read_hdf to_hdf
binário Formato Feather read_feather to_feather
binário Formato Parquet read_parquet to_parquet
binário Formato ORC read_orc
binário Msgpack read_msgpack to_msgpack
binário Stata read_stata to_stata
binário SAS read_sas
binário SPSS read_spss
binário Formato de Pickle do Python read_pickle to_pickle
SQL SQL read_sql to_sql
SQL Google BigQuery read_gbq to_gbq

11. Indexação em DataFrameslink image 176

Há muitas maneiras de indexar em DataFrames.

fechas = pd.date_range('1/1/2000', periods=8)
      dataframe = pd.DataFrame(np.random.randn(8, 4), index=fechas, columns=['A', 'B', 'C', 'D'])
      
      dataframe
      
Out[56]:
A B C D
2000-01-01 -0.869298 -0.210502 0.477938 0.912121
2000-01-02 -0.502425 -1.897287 -0.084122 -1.203818
2000-01-03 -0.204297 0.711485 -1.271802 -0.138120
2000-01-04 1.512985 0.726718 0.960902 0.433124
2000-01-05 0.724005 -2.127668 0.674417 -0.297808
2000-01-06 -0.217175 -0.621172 0.668163 0.170576
2000-01-07 0.352484 0.260515 -1.576033 1.263213
2000-01-08 -0.032928 -0.648313 -0.622509 0.231683

11.1. Indexação de colunaslink image 177

Para selecionar colunas dentro de um DataFrame, podemos fazer isso selecionando a coluna entre colchetes [], ou indicando a coluna como se fosse um atributo do DataFrame.

	
dataframe['A']
Copy
	
2000-01-01 0.813153
2000-01-02 -0.244584
2000-01-03 0.125729
2000-01-04 0.352275
2000-01-05 -2.050976
2000-01-06 -0.312296
2000-01-07 0.897837
2000-01-08 0.271403
Freq: D, Name: A, dtype: float64
	
dataframe.A
Copy
	
2000-01-01 0.813153
2000-01-02 -0.244584
2000-01-03 0.125729
2000-01-04 0.352275
2000-01-05 -2.050976
2000-01-06 -0.312296
2000-01-07 0.897837
2000-01-08 0.271403
Freq: D, Name: A, dtype: float64

Se algumas linhas específicas forem desejadas, elas são passadas por meio de uma lista.

dataframe[ ['A', 'B'] ]
      
Out[ ]:
A B
2000-01-01 -0.341962 0.639913
2000-01-02 0.507258 -0.942036
2000-01-03 -1.463557 1.041023
2000-01-04 1.781058 -1.849352
2000-01-05 0.318897 -0.229218
2000-01-06 0.362064 -0.193479
2000-01-07 -0.084632 -0.112474
2000-01-08 0.739424 0.253191

11.2. Indexação de linhas por posiçõeslink image 178

Pode-se selecionar um intervalo de linhas de um DataFrame da seguinte maneira

dataframe[0:3]
      
Out[ ]:
A B C D
2000-01-01 0.813153 -0.869356 0.934293 0.338644
2000-01-02 -0.244584 0.536352 0.322248 0.238903
2000-01-03 0.125729 2.046910 -0.877466 -0.710034

Se quiser selecionar apenas uma linha, é necessário indicar um intervalo de linhas que inclua apenas essa. Se, por exemplo, quiser selecionar a linha número 1

dataframe[1:2]
      
Out[ ]:
A B C D
2000-01-02 -0.244584 0.536352 0.322248 0.238903

Outro método para selecionar uma linha pela sua posição é o método iloc[]

dataframe.iloc[0:3]
      
Out[ ]:
A B C D
2000-01-01 0.813153 -0.869356 0.934293 0.338644
2000-01-02 -0.244584 0.536352 0.322248 0.238903
2000-01-03 0.125729 2.046910 -0.877466 -0.710034

Se quisiser algumas linhas específicas, passa-se uma lista com suas posições.

dataframe.iloc[ [0, 2, 4] ]
      
Out[ ]:
A B C D
2000-01-01 -0.341962 0.639913 0.765817 0.056692
2000-01-03 -1.463557 1.041023 -1.321715 2.822735
2000-01-05 0.318897 -0.229218 -1.095593 -0.186248

11.3. Indexação de linhas por rótuloslink image 179

Para selecionar uma linha pelas suas etiquetas podemos usar o método loc[]

	
dataframe.loc['2000-01-01']
Copy
	
A 0.813153
B -0.869356
C 0.934293
D 0.338644
Name: 2000-01-01 00:00:00, dtype: float64

Se quiser selecionar um intervalo de linhas, podemos indexá-las usando os dois pontos :

dataframe.loc['2000-01-01':'2000-01-03']
      
Out[ ]:
A B C D
2000-01-01 0.813153 -0.869356 0.934293 0.338644
2000-01-02 -0.244584 0.536352 0.322248 0.238903
2000-01-03 0.125729 2.046910 -0.877466 -0.710034

Se querem algumas linhas específicas, elas são passadas por meio de uma lista.

dataframe.loc[ ['2000-01-01', '2000-01-03', '2000-01-05'] ]
      
Out[ ]:
A B C D
2000-01-01 -0.341962 0.639913 0.765817 0.056692
2000-01-03 -1.463557 1.041023 -1.321715 2.822735
2000-01-05 0.318897 -0.229218 -1.095593 -0.186248

11.4. Seleção de uma porção do DataFrame por posiçõeslink image 180

dataframe.iloc[0:3, 0:2]
      
Out[ ]:
A B
2000-01-01 0.813153 -0.869356
2000-01-02 -0.244584 0.536352
2000-01-03 0.125729 2.046910

Se quisiser linhas e colunas específicas, passam-se listas com as posições desejadas.

dataframe.iloc[ [0, 2, 4], [0, 2] ]
      
Out[ ]:
A C
2000-01-01 -0.341962 0.765817
2000-01-03 -1.463557 -1.321715
2000-01-05 0.318897 -1.095593

11.5. Seleção de uma porção do DataFrame por meio de rótuloslink image 181

dataframe.loc['2000-01-01':'2000-01-03', 'A':'B']
      
Out[ ]:
A B
2000-01-01 0.813153 -0.869356
2000-01-02 -0.244584 0.536352
2000-01-03 0.125729 2.046910

Se querem algumas linhas e colunas específicas, passam-se listas com as etiquetas desejadas

dataframe.loc[ ['2000-01-01', '2000-01-03', '2000-01-05'], ['A', 'C'] ]
      
Out[ ]:
A C
2000-01-01 -0.341962 0.765817
2000-01-03 -1.463557 -1.321715
2000-01-05 0.318897 -1.095593

11.6. Indexação por função lambdalink image 182

Dados podem ser selecionados de um DataFrame que atendam a uma condição fornecida por uma função lambda

dataframe.loc[lambda dataframe:2*dataframe['A']+5*np.exp(dataframe['B'])>0.2]
      
Out[58]:
A B C D
2000-01-01 -0.869298 -0.210502 0.477938 0.912121
2000-01-03 -0.204297 0.711485 -1.271802 -0.138120
2000-01-04 1.512985 0.726718 0.960902 0.433124
2000-01-05 0.724005 -2.127668 0.674417 -0.297808
2000-01-06 -0.217175 -0.621172 0.668163 0.170576
2000-01-07 0.352484 0.260515 -1.576033 1.263213
2000-01-08 -0.032928 -0.648313 -0.622509 0.231683

Como se pode ver, esta forma de indexação é muito poderosa

11.7. Indexação condicionallink image 183

Se não precisamos de funções complexas para indexar, mas apenas condicionais, podemos fazer

dataframe[dataframe['A']>0.2]
      
Out[61]:
A B C D
2000-01-04 1.512985 0.726718 0.960902 0.433124
2000-01-05 0.724005 -2.127668 0.674417 -0.297808
2000-01-07 0.352484 0.260515 -1.576033 1.263213

Podemos fazer múltiplas condições

dataframe[(dataframe['A']>0.2) & (dataframe['B']>0.2)]
      
Out[69]:
A B C D
2000-01-04 1.512985 0.726718 0.960902 0.433124
2000-01-07 0.352484 0.260515 -1.576033 1.263213

11.8. Indexação aleatórialink image 184

Através do método sample() obteremos uma linha aleatória do DataFrame.

dataframe.sample()
      
Out[ ]:
A B C D
2000-01-06 -0.312296 0.129097 -0.991085 1.704535

Se quisermos mais de uma amostra, indicamos com o atributo n

dataframe.sample(n=3)
      
Out[ ]:
A B C D
2000-01-08 0.271403 1.527116 0.144970 1.175728
2000-01-01 0.813153 -0.869356 0.934293 0.338644
2000-01-03 0.125729 2.046910 -0.877466 -0.710034

Se axis=1 for o que se quer são colunas aleatórias, deve-se indicar isso.

dataframe.sample(axis=1)
      
Out[ ]:
D
2000-01-01 0.338644
2000-01-02 0.238903
2000-01-03 -0.710034
2000-01-04 0.504410
2000-01-05 -1.601926
2000-01-06 1.704535
2000-01-07 -0.584860
2000-01-08 1.175728

Se quiser um único item do DataFrame, é necessário chamar o método sample() duas vezes.

dataframe.sample(axis=1).sample()
      
Out[ ]:
D
2000-01-05 -1.601926

12. Junção de DataFrameslink image 185

12.1. Concatenação de DataFrameslink image 186

Para concatenar vários DataFrames usamos o método concat(), onde será passada uma lista com os DataFrames que se querem unir.

	
dataframe1 = pd.DataFrame(
{
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
})
dataframe2 = pd.DataFrame(
{
"A": ["A4", "A5", "A6", "A7"],
"B": ["B4", "B5", "B6", "B7"],
"C": ["C4", "C5", "C6", "C7"],
"D": ["D4", "D5", "D6", "D7"],
})
dataframe3 = pd.DataFrame(
{
"A": ["A8", "A9", "A10", "A11"],
"B": ["B8", "B9", "B10", "B11"],
"C": ["C8", "C9", "C10", "C11"],
"D": ["D8", "D9", "D10", "D11"],
})
dataframe = pd.concat([dataframe1, dataframe2, dataframe3])
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"dataframe3:\n{dataframe3}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
dataframe2:
A B C D
0 A4 B4 C4 D4
1 A5 B5 C5 D5
2 A6 B6 C6 D6
3 A7 B7 C7 D7
dataframe3:
A B C D
0 A8 B8 C8 D8
1 A9 B9 C9 D9
2 A10 B10 C10 D10
3 A11 B11 C11 D11
dataframe:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
0 A4 B4 C4 D4
1 A5 B5 C5 D5
2 A6 B6 C6 D6
3 A7 B7 C7 D7
0 A8 B8 C8 D8
1 A9 B9 C9 D9
2 A10 B10 C10 D10
3 A11 B11 C11 D11

Como pode ser visto, os índices 0, 1, 2 e 3 se repetem, porque cada dataframe possui esses índices. Para evitar isso, é necessário usar o parâmetro ignore_index=True

	
dataframe = pd.concat([dataframe1, dataframe2, dataframe3], ignore_index=True)
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"dataframe3:\n{dataframe3}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
dataframe2:
A B C D
0 A4 B4 C4 D4
1 A5 B5 C5 D5
2 A6 B6 C6 D6
3 A7 B7 C7 D7
dataframe3:
A B C D
0 A8 B8 C8 D8
1 A9 B9 C9 D9
2 A10 B10 C10 D10
3 A11 B11 C11 D11
dataframe:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11

concat

Se axis=1 tivesse sido utilizado, a concatenação teria ocorrido ao longo das colunas.

	
dataframe = pd.concat([dataframe1, dataframe2, dataframe3], axis=1)
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"dataframe3:\n{dataframe3}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
dataframe2:
A B C D
0 A4 B4 C4 D4
1 A5 B5 C5 D5
2 A6 B6 C6 D6
3 A7 B7 C7 D7
dataframe3:
A B C D
0 A8 B8 C8 D8
1 A9 B9 C9 D9
2 A10 B10 C10 D10
3 A11 B11 C11 D11
dataframe:
A B C D A B C D A B C D
0 A0 B0 C0 D0 A4 B4 C4 D4 A8 B8 C8 D8
1 A1 B1 C1 D1 A5 B5 C5 D5 A9 B9 C9 D9
2 A2 B2 C2 D2 A6 B6 C6 D6 A10 B10 C10 D10
3 A3 B3 C3 D3 A7 B7 C7 D7 A11 B11 C11 D11

12.1.1. Interseção de concatenaçãolink image 187

Há duas maneiras de fazer a concatenação, pegando todos os índices dos DataFrames ou pegando apenas os que coincidem. Isso é determinado pela variável join, que aceita os valores 'outer' (padrão) (pega todos os índices) ou 'inner' (apenas os que coincidem).

Vamos ver um exemplo de 'outer'

	
dataframe1 = pd.DataFrame(
{
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
},
index=[0, 1, 2, 3])
dataframe4 = pd.DataFrame(
{
"B": ["B2", "B3", "B6", "B7"],
"D": ["D2", "D3", "D6", "D7"],
"F": ["F2", "F3", "F6", "F7"],
},index=[2, 3, 6, 7])
dataframe = pd.concat([dataframe1, dataframe4], axis=1)
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe4}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
dataframe2:
B D F
2 B2 D2 F2
3 B3 D3 F3
6 B6 D6 F6
7 B7 D7 F7
dataframe:
A B C D B D F
0 A0 B0 C0 D0 NaN NaN NaN
1 A1 B1 C1 D1 NaN NaN NaN
2 A2 B2 C2 D2 B2 D2 F2
3 A3 B3 C3 D3 B3 D3 F3
6 NaN NaN NaN NaN B6 D6 F6
7 NaN NaN NaN NaN B7 D7 F7

outlier

Vamos ver um exemplo de 'inner'

	
dataframe = pd.concat([dataframe1, dataframe4], axis=1, join="inner")
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe4}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
dataframe2:
B D F
2 B2 D2 F2
3 B3 D3 F3
6 B6 D6 F6
7 B7 D7 F7
dataframe:
A B C D B D F
2 A2 B2 C2 D2 B2 D2 F2
3 A3 B3 C3 D3 B3 D3 F3

inner

12.2. Merge de DataFrameslink image 188

Antes criamos um novo dataframe com a união de vários dataframes, agora podemos completar um dataframe com outro, para isso usamos merge, passando o parâmetro on, sobre qual coluna queremos que seja feito o merge.

	
dataframe1 = pd.DataFrame(
{
"Key": ["K0", "K1", "K2", "K3"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
})
dataframe2 = pd.DataFrame(
{
"Key": ["K0", "K1", "K2", "K3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
})
dataframe = dataframe1.merge(dataframe2, on="Key")
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
Key A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 B2
3 K3 A3 B3
dataframe2:
Key C D
0 K0 C0 D0
1 K1 C1 D1
2 K2 C2 D2
3 K3 C3 D3
dataframe:
Key A B C D
0 K0 A0 B0 C0 D0
1 K1 A1 B1 C1 D1
2 K2 A2 B2 C2 D2
3 K3 A3 B3 C3 D3

Neste caso, os dois dataframes tinham uma chave com o mesmo nome (Key), mas no caso de termos dataframes em que suas chaves tenham nomes diferentes, podemos usar os parâmetros left_on e right_on.

	
dataframe1 = pd.DataFrame(
{
"Key1": ["K0", "K1", "K2", "K3"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
})
dataframe2 = pd.DataFrame(
{
"Key2": ["K0", "K1", "K2", "K3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
})
dataframe = dataframe1.merge(dataframe2, left_on="Key1", right_on="Key2")
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
Key1 A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 B2
3 K3 A3 B3
dataframe2:
Key2 C D
0 K0 C0 D0
1 K1 C1 D1
2 K2 C2 D2
3 K3 C3 D3
dataframe:
Key1 A B Key2 C D
0 K0 A0 B0 K0 C0 D0
1 K1 A1 B1 K1 C1 D1
2 K2 A2 B2 K2 C2 D2
3 K3 A3 B3 K3 C3 D3

No caso de uma das chaves não corresponder, o merge não será realizado sobre essa chave.

	
dataframe1 = pd.DataFrame(
{
"Key1": ["K0", "K1", "K2", "K3"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
})
dataframe2 = pd.DataFrame(
{
"Key2": ["K0", "K1", "K2", np.nan],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
})
dataframe = dataframe1.merge(dataframe2, left_on="Key1", right_on="Key2")
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
Key1 A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 B2
3 K3 A3 B3
dataframe2:
Key2 C D
0 K0 C0 D0
1 K1 C1 D1
2 K2 C2 D2
3 NaN C3 D3
dataframe:
Key1 A B Key2 C D
0 K0 A0 B0 K0 C0 D0
1 K1 A1 B1 K1 C1 D1
2 K2 A2 B2 K2 C2 D2

Para mudar esse comportamento,我们可以使用参数 how,其默认值为 inner,但我们可以传递 leftrightouter 值。

(Note: The part after "我们可以使用参数" is in Chinese. I assume it's a mistake and should be in Portuguese as requested. Here is the corrected version.)

Para mudar esse comportamento, podemos usar o parâmetro how, que por padrão tem o valor inner, mas podemos passar os valores left, right e outer.

	
dataframe1 = pd.DataFrame(
{
"Key1": ["K0", "K1", "K2", "K3"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
})
dataframe2 = pd.DataFrame(
{
"Key2": ["K0", "K1", "K2", np.nan],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
})
dataframe_inner = dataframe1.merge(dataframe2, left_on="Key1", right_on="Key2", how="inner")
dataframe_left = dataframe1.merge(dataframe2, left_on="Key1", right_on="Key2", how="left")
dataframe_right = dataframe1.merge(dataframe2, left_on="Key1", right_on="Key2", how="right")
dataframe_outer = dataframe1.merge(dataframe2, left_on="Key1", right_on="Key2", how="outer")
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"\ndataframe inner:\n{dataframe_inner}")
print(f"\ndataframe left:\n{dataframe_left}")
print(f"\ndataframe right:\n{dataframe_right}")
print(f"\ndataframe outer:\n{dataframe_outer}")
Copy
	
dataframe1:
Key1 A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 B2
3 K3 A3 B3
dataframe2:
Key2 C D
0 K0 C0 D0
1 K1 C1 D1
2 K2 C2 D2
3 NaN C3 D3
dataframe inner:
Key1 A B Key2 C D
0 K0 A0 B0 K0 C0 D0
1 K1 A1 B1 K1 C1 D1
2 K2 A2 B2 K2 C2 D2
dataframe left:
Key1 A B Key2 C D
0 K0 A0 B0 K0 C0 D0
1 K1 A1 B1 K1 C1 D1
2 K2 A2 B2 K2 C2 D2
3 K3 A3 B3 NaN NaN NaN
dataframe right:
Key1 A B Key2 C D
0 K0 A0 B0 K0 C0 D0
1 K1 A1 B1 K1 C1 D1
2 K2 A2 B2 K2 C2 D2
3 NaN NaN NaN NaN C3 D3
dataframe outer:
Key1 A B Key2 C D
0 K0 A0 B0 K0 C0 D0
1 K1 A1 B1 K1 C1 D1
2 K2 A2 B2 K2 C2 D2
3 K3 A3 B3 NaN NaN NaN
4 NaN NaN NaN NaN C3 D3

Como pode ser visto, quando se escolhe left são adicionados apenas os valores do dataframe da esquerda e quando se escolhe right, os valores do dataframe da direita.

12.3. Join de dataframeslink image 189

A última ferramenta de junção de dataframes é join. É semelhante a merge, apenas em vez de procurar similaridades com base em colunas especificadas, ela as procura com base nos índices.

	
dataframe1 = pd.DataFrame(
{
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
},
index=["K0", "K1", "K2", "K3"])
dataframe2 = pd.DataFrame(
{
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
},
index=["K0", "K1", "K2", "K3"])
dataframe = dataframe1.join(dataframe2)
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"\ndataframe:\n{dataframe}")
Copy
	
dataframe1:
A B
K0 A0 B0
K1 A1 B1
K2 A2 B2
K3 A3 B3
dataframe2:
C D
K0 C0 D0
K1 C1 D1
K2 C2 D2
K3 C3 D3
dataframe:
A B C D
K0 A0 B0 C0 D0
K1 A1 B1 C1 D1
K2 A2 B2 C2 D2
K3 A3 B3 C3 D3

Neste caso, os índices são iguais, mas quando são diferentes podemos especificar a maneira de unir os dataframes através do parâmetro how, que por padrão tem o valor inner, mas pode ter o valor left, right ou outer.

	
dataframe1 = pd.DataFrame(
{
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
},
index=["K0", "K1", "K2", "K3"])
dataframe2 = pd.DataFrame(
{
"C": ["C0", "C2", "C3", "C4"],
"D": ["D0", "D2", "D3", "D4"],
},
index=["K0", "K2", "K3", "K4"])
dataframe_inner = dataframe1.join(dataframe2, how="inner")
dataframe_left = dataframe1.join(dataframe2, how="left")
dataframe_right = dataframe1.join(dataframe2, how="right")
dataframe_outer = dataframe1.join(dataframe2, how="outer")
print(f"dataframe1:\n{dataframe1}")
print(f"dataframe2:\n{dataframe2}")
print(f"\ndataframe inner:\n{dataframe_inner}")
print(f"\ndataframe left:\n{dataframe_left}")
print(f"\ndataframe rigth:\n{dataframe_right}")
print(f"\ndataframe outer:\n{dataframe_outer}")
Copy
	
dataframe1:
A B
K0 A0 B0
K1 A1 B1
K2 A2 B2
K3 A3 B3
dataframe2:
C D
K0 C0 D0
K2 C2 D2
K3 C3 D3
K4 C4 D4
dataframe:
A B C D
K0 A0 B0 C0 D0
K2 A2 B2 C2 D2
K3 A3 B3 C3 D3
dataframe:
A B C D
K0 A0 B0 C0 D0
K1 A1 B1 NaN NaN
K2 A2 B2 C2 D2
K3 A3 B3 C3 D3
dataframe:
A B C D
K0 A0 B0 C0 D0
K2 A2 B2 C2 D2
K3 A3 B3 C3 D3
K4 NaN NaN C4 D4
dataframe:
A B C D
K0 A0 B0 C0 D0
K1 A1 B1 NaN NaN
K2 A2 B2 C2 D2
K3 A3 B3 C3 D3
K4 NaN NaN C4 D4

13. Dados faltantes (NaN)link image 190

Em um DataFrame podem haver alguns dados faltantes, o Pandas os representa como np.nan

diccionario = {
          "uno": pd.Series([1.0, 2.0, 3.0]),
          "dos": pd.Series([4.0, 5.0, 6.0, 7.0])
          }
      
      dataframe = pd.DataFrame(diccionario)
      dataframe
      
Out[ ]:
uno dos
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
3 NaN 7.0

13.1. Eliminação das linhas com dados faltanteslink image 191

Para não ter linhas com dados faltantes, essas podem ser eliminadas.

dataframe.dropna(how="any")
      
Out[ ]:
uno dos
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0

13.2. Eliminação das colunas com dados faltanteslink image 192

dataframe.dropna(axis=1, how='any')
      
Out[ ]:
dos
0 4.0
1 5.0
2 6.0
3 7.0

13.3. Máscara booleana com as posições faltanteslink image 193

pd.isna(dataframe)
      
Out[ ]:
uno dos
0 False False
1 False False
2 False False
3 True False

13.4. Preenchimento dos dados ausenteslink image 194

dataframe.fillna(value=5.5, inplace=True)
      dataframe
      
Out[ ]:
uno dos
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
3 5.5 7.0

Dica: Colocando a variável inplace=True modifica o DataFrame sobre o qual está sendo operado, assim não é necessário escrever dataframe = dataframe.fillna(value=5.5)

14. Séries Temporaislink image 195

Pandas oferece a possibilidade de trabalhar com séries temporais. Por exemplo, criamos uma Serie de 100 dados aleatórios a cada segundo a partir de 01/01/2021

	
indices = pd.date_range("1/1/2021", periods=100, freq="S")
datos = np.random.randint(0, 500, len(indices))
serie_temporal = pd.Series(datos, index=indices)
serie_temporal
Copy
	
2021-01-01 00:00:00 241
2021-01-01 00:00:01 14
2021-01-01 00:00:02 190
2021-01-01 00:00:03 407
2021-01-01 00:00:04 94
...
2021-01-01 00:01:35 275
2021-01-01 00:01:36 56
2021-01-01 00:01:37 448
2021-01-01 00:01:38 151
2021-01-01 00:01:39 316
Freq: S, Length: 100, dtype: int64

Esta funcionalidade do Pandas é muito poderosa, por exemplo, podemos ter um conjunto de dados em certas horas de um fuso horário e alterá-las para outro fuso.

	
horas = pd.date_range("3/6/2021 00:00", periods=10, freq="H")
datos = np.random.randn(len(horas))
serie_horaria = pd.Series(datos, horas)
serie_horaria
Copy
	
2021-03-06 00:00:00 -0.853524
2021-03-06 01:00:00 -1.355372
2021-03-06 02:00:00 -1.267503
2021-03-06 03:00:00 -1.155787
2021-03-06 04:00:00 0.730935
2021-03-06 05:00:00 1.435957
2021-03-06 06:00:00 0.460912
2021-03-06 07:00:00 0.723451
2021-03-06 08:00:00 -0.853337
2021-03-06 09:00:00 0.456359
Freq: H, dtype: float64

Localizamos os dados em um fuso horário

	
serie_horaria_utc = serie_horaria.tz_localize("UTC")
serie_horaria_utc
Copy
	
2021-03-06 00:00:00+00:00 -0.853524
2021-03-06 01:00:00+00:00 -1.355372
2021-03-06 02:00:00+00:00 -1.267503
2021-03-06 03:00:00+00:00 -1.155787
2021-03-06 04:00:00+00:00 0.730935
2021-03-06 05:00:00+00:00 1.435957
2021-03-06 06:00:00+00:00 0.460912
2021-03-06 07:00:00+00:00 0.723451
2021-03-06 08:00:00+00:00 -0.853337
2021-03-06 09:00:00+00:00 0.456359
Freq: H, dtype: float64

E agora podemos alterá-las para outro uso

	
serie_horaria_US = serie_horaria_utc.tz_convert("US/Eastern")
serie_horaria_US
Copy
	
2021-03-05 19:00:00-05:00 -0.853524
2021-03-05 20:00:00-05:00 -1.355372
2021-03-05 21:00:00-05:00 -1.267503
2021-03-05 22:00:00-05:00 -1.155787
2021-03-05 23:00:00-05:00 0.730935
2021-03-06 00:00:00-05:00 1.435957
2021-03-06 01:00:00-05:00 0.460912
2021-03-06 02:00:00-05:00 0.723451
2021-03-06 03:00:00-05:00 -0.853337
2021-03-06 04:00:00-05:00 0.456359
Freq: H, dtype: float64

15. Dados categóricoslink image 196

Pandas oferece a possibilidade de adicionar dados categóricos em um DataFrame. Suponha o seguinte DataFrame

dataframe = pd.DataFrame(
          {"id": [1, 2, 3, 4, 5, 6], "raw_grade": ["a", "b", "b", "a", "a", "e"]}
      )
      
      dataframe
      
Out[2]:
id raw_grade
0 1 a
1 2 b
2 3 b
3 4 a
4 5 a
5 6 e

Podemos converter os dados da coluna raw_grade para dados categóricos através do método astype()

dataframe['grade'] = dataframe["raw_grade"].astype("category")
      
      dataframe
      
Out[3]:
id raw_grade grade
0 1 a a
1 2 b b
2 3 b b
3 4 a a
4 5 a a
5 6 e e

As colunas raw_grade e grade parecem iguais, mas se olharmos as informações do DataFrame, podemos ver que não é assim.

	
dataframe.info()
Copy
	
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 6 non-null int64
1 raw_grade 6 non-null object
2 grade 6 non-null category
dtypes: category(1), int64(1), object(1)
memory usage: 334.0+ bytes

Pode-se ver que a coluna grade é do tipo categórico

Podemos ver as categorias dos tipos de dados categóricos através do método cat.categories()

	
dataframe["grade"].cat.categories
Copy
	
Index(['a', 'b', 'e'], dtype='object')

Também podemos renomear as categorias com o mesmo método, mas introduzindo uma lista com as novas categorias.

dataframe["grade"].cat.categories = ["very good", "good", "very bad"]
      dataframe
      
Out[7]:
id raw_grade grade
0 1 a very good
1 2 b good
2 3 b good
3 4 a very good
4 5 a very good
5 6 e very bad

Pandas nos dá a possibilidade de codificar numericamente os dados categóricos através do método get_dummies

pd.get_dummies(dataframe["grade"])
      
Out[8]:
very good good very bad
0 1 0 0
1 0 1 0
2 0 1 0
3 1 0 0
4 1 0 0
5 0 0 1

16. Groupbylink image 197

Podemos agrupar os dataframes pelos valores de alguma das colunas. Vamos recarregar o dataframe com o valor das casas da Califórnia.

california_housing_train = pd.read_csv("https://raw.githubusercontent.com/maximofn/portafolio/main/posts/california_housing_train.csv")
      california_housing_train.head()
      
Out[43]:
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
0 -114.31 34.19 15.0 5612.0 1283.0 1015.0 472.0 1.4936 66900.0
1 -114.47 34.40 19.0 7650.0 1901.0 1129.0 463.0 1.8200 80100.0
2 -114.56 33.69 17.0 720.0 174.0 333.0 117.0 1.6509 85700.0
3 -114.57 33.64 14.0 1501.0 337.0 515.0 226.0 3.1917 73400.0
4 -114.57 33.57 20.0 1454.0 326.0 624.0 262.0 1.9250 65500.0

Agora podemos agrupar os dados por alguma das colunas, por exemplo, agrupemos as casas em função do número de anos e vejamos quantas casas há de cada idade com count

california_housing_train.groupby("housing_median_age").count().head()
      
Out[8]:
longitude latitude total_rooms total_bedrooms population households median_income median_house_value
housing_median_age
1.0 2 2 2 2 2 2 2 2
2.0 49 49 49 49 49 49 49 49
3.0 46 46 46 46 46 46 46 46
4.0 161 161 161 161 161 161 161 161
5.0 199 199 199 199 199 199 199 199

Como vemos em todas as colunas, obtemos o mesmo valor, que é o número de casas que há com uma determinada idade, mas podemos saber a média do valor de cada coluna com mean

california_housing_train.groupby("housing_median_age").mean().head()
      
Out[9]:
longitude latitude total_rooms total_bedrooms population households median_income median_house_value
housing_median_age
1.0 -121.465000 37.940000 2158.000000 335.500000 637.000000 190.000000 4.756800 190250.000000
2.0 -119.035306 35.410816 5237.102041 871.448980 2005.224490 707.122449 5.074237 229438.836735
3.0 -118.798478 35.164783 6920.326087 1190.826087 2934.673913 1030.413043 5.572013 239450.043478
4.0 -118.805093 34.987764 6065.614907 1068.192547 2739.956522 964.291925 5.196055 230054.105590
5.0 -118.789497 35.095327 4926.261307 910.924623 2456.979899 826.768844 4.732460 211035.708543

Podemos obter várias medidas de cada idade através do comando agg (agregação), passando-lhe as medidas que queremos por meio de uma lista, por exemplo, vejamos o mínimo, o máximo e a média de cada coluna para cada idade de cada

california_housing_train.groupby("housing_median_age").agg(['min', 'max', 'mean']).head()
      
Out[10]:
longitude latitude total_rooms total_bedrooms ... population households median_income median_house_value
min max mean min max mean min max mean min ... mean min max mean min max mean min max mean
housing_median_age
1.0 -122.00 -120.93 -121.465000 37.65 38.23 37.940000 2062.0 2254.0 2158.000000 328.0 ... 637.000000 112.0 268.0 190.000000 4.2500 5.2636 4.756800 189200.0 191300.0 190250.000000
2.0 -122.51 -115.80 -119.035306 33.16 40.58 35.410816 96.0 21897.0 5237.102041 18.0 ... 2005.224490 16.0 2873.0 707.122449 1.9667 10.1531 5.074237 47500.0 500001.0 229438.836735
3.0 -122.33 -115.60 -118.798478 32.87 38.77 35.164783 475.0 21060.0 6920.326087 115.0 ... 2934.673913 123.0 3112.0 1030.413043 2.1187 11.5199 5.572013 83200.0 500001.0 239450.043478
4.0 -122.72 -116.76 -118.805093 32.65 39.00 34.987764 2.0 37937.0 6065.614907 2.0 ... 2739.956522 2.0 5189.0 964.291925 0.5360 13.4883 5.196055 42500.0 500001.0 230054.105590
5.0 -122.55 -115.55 -118.789497 32.55 40.60 35.095327 111.0 25187.0 4926.261307 21.0 ... 2456.979899 20.0 3886.0 826.768844 0.7526 12.6320 4.732460 50000.0 500001.0 211035.708543

5 rows × 24 columns

Podemos especificar sobre quais colunas queremos realizar certos cálculos através da passagem de um dicionário, onde as chaves serão as colunas sobre as quais queremos realizar cálculos e os valores serão listas com os cálculos.

california_housing_train.groupby("housing_median_age").agg({'total_rooms': ['min', 'max', 'mean'], 'total_bedrooms': ['min', 'max', 'mean', 'median']}).head()
      
Out[12]:
total_rooms total_bedrooms
min max mean min max mean median
housing_median_age
1.0 2062.0 2254.0 2158.000000 328.0 343.0 335.500000 335.5
2.0 96.0 21897.0 5237.102041 18.0 3513.0 871.448980 707.0
3.0 475.0 21060.0 6920.326087 115.0 3559.0 1190.826087 954.0
4.0 2.0 37937.0 6065.614907 2.0 5471.0 1068.192547 778.0
5.0 111.0 25187.0 4926.261307 21.0 4386.0 910.924623 715.0

Podemos agrupar por mais de uma coluna, para isso, é necessário passar as colunas em uma lista

california_housing_train.groupby(["housing_median_age", "total_bedrooms"]).mean()
      
Out[16]:
longitude latitude total_rooms population households median_income median_house_value
housing_median_age total_bedrooms
1.0 328.0 -120.93 37.65 2254.0 402.0 112.0 4.2500 189200.0
343.0 -122.00 38.23 2062.0 872.0 268.0 5.2636 191300.0
2.0 18.0 -115.80 33.26 96.0 30.0 16.0 5.3374 47500.0
35.0 -121.93 37.78 227.0 114.0 49.0 3.1591 434700.0
55.0 -117.27 33.93 337.0 115.0 49.0 3.1042 164800.0
... ... ... ... ... ... ... ... ...
52.0 1360.0 -118.35 34.06 3446.0 1768.0 1245.0 2.4722 500001.0
1535.0 -122.41 37.80 3260.0 3260.0 1457.0 0.9000 500001.0
1944.0 -118.25 34.05 2806.0 2232.0 1605.0 0.6775 350000.0
2509.0 -122.41 37.79 6016.0 3436.0 2119.0 2.5166 275000.0
2747.0 -122.41 37.79 5783.0 4518.0 2538.0 1.7240 225000.0

13394 rows × 7 columns

17. Gráficoslink image 198

Pandas oferece a possibilidade de representar os dados dos nossos DataFrames em gráficos para poder obter uma melhor representação deles. Para isso, utiliza a biblioteca matplotlib, que veremos no próximo post.

17.1. Gráfico básicolink image 199

Para representar os dados em um gráfico, a maneira mais fácil é usar o método plot()

serie = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))
      serie = serie.cumsum()
      
      serie.plot()
      
Out[13]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5666b9990>
image pandas 1

No caso de ter um DataFrame, o método plot() representará cada uma das colunas do DataFrame

dataframe = pd.DataFrame(
          np.random.randn(1000, 4), index=ts.index, columns=["A", "B", "C", "D"]
      )
      dataframe = dataframe.cumsum()
      
      dataframe.plot()
      
Out[15]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5663ce610>
image pandas 2

17.2. Diagrama de barras verticaislink image 200

Há mais métodos para criar gráficos, como o gráfico de barras vertical através de plot.bar()

dataframe = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
      dataframe.plot.bar()
      
image pandas 3

Se quisermos empilhar as barras, indicamos isso através da variável stacked=True

dataframe.plot.bar(stacked=True)
      
Out[20]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc56265c5d0>
image pandas 4

17.3. Diagrama de barras horizontallink image 201

Para criar um diagrama de barras horizontal usamos plot.barh()

dataframe.plot.barh()
      
Out[21]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc56247fa10>
image pandas 5

Se quisermos empilhar as barras, indicamos isso através da variável stacked=True

dataframe.plot.barh(stacked=True)
      
Out[22]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc562d1d2d0>
image pandas 6

17.4. Histogramalink image 202

Para criar um histograma usamos plot.hist()

dataframe = pd.DataFrame(
          {
              "a": np.random.randn(1000) + 1,
              "b": np.random.randn(1000),
              "c": np.random.randn(1000) - 1,
          }
      )
      
      dataframe.plot.hist(alpha=0.5)
      
Out[28]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5650711d0>
image pandas 7

Se quisermos empilhar as barras, indicamos isso através da variável stacked=True

dataframe.plot.hist(alpha=0.5, stacked=True)
      
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5625779d0>
image pandas 8

Se quisermos adicionar mais colunas, ou seja, se quisermos que o histograma seja mais informativo ou preciso, indicamos isso através da variável bins

dataframe.plot.hist(alpha=0.5, stacked=True, bins=20)
      
Out[30]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc562324990>
image pandas 9

17.5. Diagramas de Velaslink image 203

Para criar um diagrama de velas usamos plot.box()

dataframe = pd.DataFrame(np.random.rand(10, 5), columns=["A", "B", "C", "D", "E"])
      
      dataframe.plot.box()
      
Out[34]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc56201a410>
image pandas 10

17.6. Gráficos de áreaslink image 204

Para criar um gráfico de áreas usamos plot.area()

dataframe.plot.area()
      
Out[36]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc561e9ca50>
image pandas 11

17.7. Diagrama de dispersãolink image 205

Para criar um diagrama de dispersão usamos plot.scatter(), onde é necessário indicar as variáveis x e y do diagrama

dataframe.plot.scatter(x='A', y='B')
      
Out[38]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc561e2ff10>
image pandas 12

17.8. Gráfico de contêiner hexagonallink image 206

Para criar um gráfico de contêiner hexagonal usamos plot.hexbin(), onde é necessário indicar as variáveis x e y do diagrama e o tamanho da malha por meio de gridsize

dataframe = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])
      dataframe["b"] = dataframe["b"] + np.arange(1000)
      
      dataframe.plot.hexbin(x="a", y="b", gridsize=25)
      
Out[40]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fc561cdded0>
image pandas 13

Continuar lendo

Últimos posts -->

Você viu esses projetos?

Subtify

Subtify Subtify

Gerador de legendas para vídeos no idioma que você desejar. Além disso, coloca uma legenda de cor diferente para cada pessoa

Ver todos os projetos -->

Quer aplicar IA no seu projeto? Entre em contato!

Quer melhorar com essas dicas?

Últimos tips -->

Use isso localmente

Os espaços do Hugging Face nos permitem executar modelos com demos muito simples, mas e se a demo quebrar? Ou se o usuário a deletar? Por isso, criei contêineres docker com alguns espaços interessantes, para poder usá-los localmente, aconteça o que acontecer. Na verdade, se você clicar em qualquer botão de visualização de projeto, ele pode levá-lo a um espaço que não funciona.

Flow edit

Flow edit Flow edit

Edite imagens com este modelo de Flow. Baseado em SD3 ou FLUX, você pode editar qualquer imagem e gerar novas

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
Ver todos os contêineres -->

Quer aplicar IA no seu projeto? Entre em contato!

Você quer treinar seu modelo com esses datasets?

short-jokes-dataset

Dataset com piadas em inglês

opus100

Dataset com traduções de inglês para espanhol

netflix_titles

Dataset com filmes e séries da Netflix

Ver mais datasets -->