Gerenciamento de dados com Pandas

Gerenciamento de dados com Pandas Gerenciamento de dados com Pandas

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 129

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.

2. O que é o Pandas?link image 130

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 pd

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 131

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

3.1. Sérieslink image 132

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 133

	
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 134

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 135

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 136

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 137

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: {serie}")
print(f" serie + serie = {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: {serie}")
print(f" exp(serie) = {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: {serie}")
print(f" serie[1:] + serie[:-1] = {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 138

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 139

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 140

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
Copy
	
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
Copy
	
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
Copy
	
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
Copy
	
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 141

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
Copy
	
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 142

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
Copy
	
columna1 columna2
a 1 3
b 2 2
c 3 1

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

	
lista = [{"a": 1, "b": 2}, {"a": 5, "b": 10, "c": 20}]
dataframe = pd.DataFrame(lista)
dataframe
Copy
	
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 144

	
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
Copy
	
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 145

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
Copy
	
0
b 1
a 0
c 2

4. Exploração de um DataFramelink image 146

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
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
... ... ... ... ... ...
16995 -124.26 40.58 52.0 2217.0 394.0
16996 -124.27 40.69 36.0 2349.0 528.0
16997 -124.30 41.84 17.0 2677.0 531.0
16998 -124.30 41.80 19.0 2672.0 552.0
16999 -124.35 40.54 52.0 1820.0 300.0
population households median_income median_house_value
0 1015.0 472.0 1.4936 66900.0
1 1129.0 463.0 1.8200 80100.0
2 333.0 117.0 1.6509 85700.0
3 515.0 226.0 3.1917 73400.0
4 624.0 262.0 1.9250 65500.0
... ... ... ... ...
16995 907.0 369.0 2.3571 111400.0
16996 1194.0 465.0 2.5179 79000.0
16997 1244.0 456.0 3.0313 103600.0
16998 1298.0 478.0 1.9797 85800.0
16999 806.0 270.0 3.0147 94600.0
[17000 rows x 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 147

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

4.2. Cauda do DataFramelink image 148

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()
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
16995 -124.26 40.58 52.0 2217.0 394.0
16996 -124.27 40.69 36.0 2349.0 528.0
16997 -124.30 41.84 17.0 2677.0 531.0
16998 -124.30 41.80 19.0 2672.0 552.0
16999 -124.35 40.54 52.0 1820.0 300.0
population households median_income median_house_value
16995 907.0 369.0 2.3571 111400.0
16996 1194.0 465.0 2.5179 79000.0
16997 1244.0 456.0 3.0313 103600.0
16998 1298.0 478.0 1.9797 85800.0
16999 806.0 270.0 3.0147 94600.0

4.3. Informação do DataFramelink image 149

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 150

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 {indices} ")
print(f"El DataFrame tiene las columnas {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 151

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()
Copy
	
longitude latitude housing_median_age total_rooms \
count 17000.000000 17000.000000 17000.000000 17000.000000
mean -119.562108 35.625225 28.589353 2643.664412
std 2.005166 2.137340 12.586937 2179.947071
min -124.350000 32.540000 1.000000 2.000000
25% -121.790000 33.930000 18.000000 1462.000000
50% -118.490000 34.250000 29.000000 2127.000000
75% -118.000000 37.720000 37.000000 3151.250000
max -114.310000 41.950000 52.000000 37937.000000
total_bedrooms population households median_income \
count 17000.000000 17000.000000 17000.000000 17000.000000
mean 539.410824 1429.573941 501.221941 3.883578
std 421.499452 1147.852959 384.520841 1.908157
min 1.000000 3.000000 1.000000 0.499900
25% 297.000000 790.000000 282.000000 2.566375
50% 434.000000 1167.000000 409.000000 3.544600
75% 648.250000 1721.000000 605.250000 4.767000
max 6445.000000 35682.000000 6082.000000 15.000100
median_house_value
count 17000.000000
mean 207300.912353
std 115983.764387
min 14999.000000
25% 119400.000000
50% 180400.000000
75% 265000.000000
max 500001.000000

4.6. Ordenação do DataFrame

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()
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
population households median_income median_house_value
0 1015.0 472.0 1.4936 66900.0
1 1129.0 463.0 1.8200 80100.0
2 333.0 117.0 1.6509 85700.0
3 515.0 226.0 3.1917 73400.0
4 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()
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
16999 -124.35 40.54 52.0 1820.0 300.0
16998 -124.30 41.80 19.0 2672.0 552.0
16997 -124.30 41.84 17.0 2677.0 531.0
16996 -124.27 40.69 36.0 2349.0 528.0
16995 -124.26 40.58 52.0 2217.0 394.0
population households median_income median_house_value
16999 806.0 270.0 3.0147 94600.0
16998 1298.0 478.0 1.9797 85800.0
16997 1244.0 456.0 3.0313 103600.0
16996 1194.0 465.0 2.5179 79000.0
16995 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()
Copy
	
households housing_median_age latitude longitude median_house_value \
0 472.0 15.0 34.19 -114.31 66900.0
1 463.0 19.0 34.40 -114.47 80100.0
2 117.0 17.0 33.69 -114.56 85700.0
3 226.0 14.0 33.64 -114.57 73400.0
4 262.0 20.0 33.57 -114.57 65500.0
median_income population total_bedrooms total_rooms
0 1.4936 1015.0 1283.0 5612.0
1 1.8200 1129.0 1901.0 7650.0
2 1.6509 333.0 174.0 720.0
3 3.1917 515.0 337.0 1501.0
4 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')
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
568 -117.02 36.40 19.0 619.0 239.0
16643 -122.74 39.71 16.0 255.0 73.0
16801 -123.17 40.31 36.0 98.0 28.0
3226 -117.86 34.24 52.0 803.0 267.0
7182 -118.33 34.15 39.0 493.0 168.0
... ... ... ... ... ...
15834 -122.42 37.81 52.0 1314.0 317.0
7927 -118.40 33.87 38.0 2398.0 431.0
3546 -117.90 33.63 28.0 2370.0 352.0
7924 -118.40 33.88 35.0 1060.0 191.0
14011 -122.04 37.26 24.0 4973.0 709.0
population households median_income median_house_value
568 490.0 164.0 2.1000 14999.0
16643 85.0 38.0 1.6607 14999.0
16801 18.0 8.0 0.5360 14999.0
3226 628.0 225.0 4.1932 14999.0
7182 259.0 138.0 2.3667 17500.0
... ... ... ... ...
15834 473.0 250.0 4.3472 500001.0
7927 911.0 392.0 5.2319 500001.0
3546 832.0 347.0 7.1148 500001.0
7924 444.0 196.0 8.0015 500001.0
14011 1692.0 696.0 7.8627 500001.0
[17000 rows x 9 columns]

4.7. Estatísticas do DataFramelink image 152

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: {california_housing_train.mean()}")
print(f" desviación estandar: {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: {california_housing_train.mean(axis=1)}")
print(f" desviación estandar: {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 153

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 154

5.1. Adição de colunaslink image 155

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
Copy
	
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
Copy
	
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
Copy
	
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
Copy
	
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
Copy
	
uno dos tres ... Menos indices columna_asignada1 columna_asignada2
0 1.0 4.0 5.0 ... 1.0 5.0 20.0
1 2.0 5.0 7.0 ... 2.0 14.0 35.0
2 3.0 6.0 9.0 ... NaN 27.0 54.0
3 NaN 7.0 NaN ... NaN NaN NaN
[4 rows x 9 columns]

5.2. Adição de linhaslink image 156

	
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()
Copy
	
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
Copy
	
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
Copy
	
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 157

6.1. Eliminação de colunaslink image 158

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

	
dataframe.pop("constante")
dataframe
Copy
	
uno dos tres ... Menos indices columna_asignada1 columna_asignada2
0 1.0 4.0 5.0 ... 1.0 5.0 20.0
1 2.0 5.0 7.0 ... 2.0 14.0 35.0
2 3.0 6.0 9.0 ... NaN 27.0 54.0
3 NaN 7.0 NaN ... NaN NaN NaN
[4 rows x 8 columns]

O mediante del

	
del dataframe["flag"]
dataframe
Copy
	
uno dos tres ... Menos indices columna_asignada1 columna_asignada2
0 1.0 4.0 5.0 ... 1.0 5.0 20.0
1 2.0 5.0 7.0 ... 2.0 14.0 35.0
2 3.0 6.0 9.0 ... NaN 27.0 54.0
3 NaN 7.0 NaN ... NaN NaN NaN
[4 rows x 7 columns]

6.1. Eliminação de linhaslink image 159

	
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()
Copy
	
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
Copy
	
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
Copy
	
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
Copy
	
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
Copy
	
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
Copy
	
uno dos tres
0 1.0 11.0 21.0
1 7.0 17.0 27.0

7. Operações sobre DataFrameslink image 160

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()
Copy
	
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
Copy
	
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"] ])
Copy
	
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()
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
population households median_income median_house_value
0 1015.0 472.0 1.4936 66900.0
1 1129.0 463.0 1.8200 80100.0
2 333.0 117.0 1.6509 85700.0
3 515.0 226.0 3.1917 73400.0
4 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()
Copy
	
CPU times: user 309 ms, sys: 86 µs, total: 309 ms
Wall time: 309 ms
	
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
population households median_income median_house_value percent_bedrooms
0 1015.0 472.0 1.4936 66900.0 0.228617
1 1129.0 463.0 1.8200 80100.0 0.248497
2 333.0 117.0 1.6509 85700.0 0.241667
3 515.0 226.0 3.1917 73400.0 0.224517
4 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()
Copy
	
/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
	
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
population households median_income median_house_value percent_bedrooms
0 1015.0 472.0 1.4936 66900.0 0.228617
1 1129.0 463.0 1.8200 80100.0 0.248497
2 333.0 117.0 1.6509 85700.0 0.241667
3 515.0 226.0 3.1917 73400.0 0.224517
4 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 161

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
Copy
	
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 162

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
Copy
	
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 163

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](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-read-csv-table) [to_csv](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-store-in-csv)
texto Arquivo de texto de largura fixa [read_fwf](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-fwf-reader)
texto JSON [read_json](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-json-reader) [to_json](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-json-writer)
texto HTML [read_html](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-read-html) [to_html](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-html)
texto Clipboard local [read_clipboard](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-clipboard) [to_clipboard](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-clipboard)
binário MS Excel [read_excel](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-excel-reader) [to_excel](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-excel-writer)
binário OpenDocument [read_excel](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-ods)
binário Formato HDF5 [read_hdf](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-hdf5) [to_hdf](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-hdf5)
binário Formato Feather [read_feather](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-feather) [to_feather](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-feather)
binário Formato Parquet [read_parquet](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-parquet) [to_parquet](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-parquet)
binário Formato ORC [read_orc](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-orc)
binário Msgpack [read_msgpack](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-msgpack) [to_msgpack](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-msgpack)
binário Stata [read_stata](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-stata-reader) [to_stata](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-stata-writer)
binário SAS [read_sas](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sas-reader)
binário SPSS [read_spss](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-spss-reader)
binário Formato de Pickle do Python [read_pickle](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-pickle) [to_pickle](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-pickle)
SQL SQL [read_sql](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql) [to_sql](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql)
SQL Google BigQuery [read_gbq](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-bigquery) [to_gbq](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-bigquery)

11. Indexação em DataFrameslink image 164

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
Copy
	
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 165

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'] ]
Copy
	
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 166

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

	
dataframe[0:3]
Copy
	
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]
Copy
	
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]
Copy
	
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] ]
Copy
	
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 167

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']
Copy
	
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'] ]
Copy
	
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 168

	
dataframe.iloc[0:3, 0:2]
Copy
	
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] ]
Copy
	
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 169

	
dataframe.loc['2000-01-01':'2000-01-03', 'A':'B']
Copy
	
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'] ]
Copy
	
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 170

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]
Copy
	
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 171

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

	
dataframe[dataframe['A']>0.2]
Copy
	
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)]
Copy
	
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 172

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

	
dataframe.sample()
Copy
	
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)
Copy
	
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)
Copy
	
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()
Copy
	
D
2000-01-05 -1.601926

12. Junção de DataFrameslink image 173

12.1. Concatenação de DataFrameslink image 174

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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f"dataframe3: {dataframe3}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f"dataframe3: {dataframe3}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f"dataframe3: {dataframe3}")
print(f" dataframe: {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 175

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: {dataframe1}")
print(f"dataframe2: {dataframe4}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe4}")
print(f" dataframe: {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 DataFrames

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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f" dataframe inner: {dataframe_inner}")
print(f" dataframe left: {dataframe_left}")
print(f" dataframe right: {dataframe_right}")
print(f" dataframe outer: {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 dataframes

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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f" dataframe: {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: {dataframe1}")
print(f"dataframe2: {dataframe2}")
print(f" dataframe inner: {dataframe_inner}")
print(f" dataframe left: {dataframe_left}")
print(f" dataframe rigth: {dataframe_right}")
print(f" dataframe outer: {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)

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
Copy
	
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 176

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

	
dataframe.dropna(how="any")
Copy
	
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 177

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

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

	
pd.isna(dataframe)
Copy
	
uno dos
0 False False
1 False False
2 False False
3 True False

13.4. Preenchimento dos dados ausenteslink image 179

	
dataframe.fillna(value=5.5, inplace=True)
dataframe
Copy
	
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 180

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 181

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
Copy
	
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
Copy
	
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
Copy
	
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"])
Copy
	
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 182

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()
Copy
	
longitude latitude housing_median_age total_rooms total_bedrooms \
0 -114.31 34.19 15.0 5612.0 1283.0
1 -114.47 34.40 19.0 7650.0 1901.0
2 -114.56 33.69 17.0 720.0 174.0
3 -114.57 33.64 14.0 1501.0 337.0
4 -114.57 33.57 20.0 1454.0 326.0
population households median_income median_house_value
0 1015.0 472.0 1.4936 66900.0
1 1129.0 463.0 1.8200 80100.0
2 333.0 117.0 1.6509 85700.0
3 515.0 226.0 3.1917 73400.0
4 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()
Copy
	
longitude latitude total_rooms total_bedrooms \
housing_median_age
1.0 2 2 2 2
2.0 49 49 49 49
3.0 46 46 46 46
4.0 161 161 161 161
5.0 199 199 199 199
population households median_income median_house_value
housing_median_age
1.0 2 2 2 2
2.0 49 49 49 49
3.0 46 46 46 46
4.0 161 161 161 161
5.0 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()
Copy
	
longitude latitude total_rooms total_bedrooms \
housing_median_age
1.0 -121.465000 37.940000 2158.000000 335.500000
2.0 -119.035306 35.410816 5237.102041 871.448980
3.0 -118.798478 35.164783 6920.326087 1190.826087
4.0 -118.805093 34.987764 6065.614907 1068.192547
5.0 -118.789497 35.095327 4926.261307 910.924623
population households median_income \
housing_median_age
1.0 637.000000 190.000000 4.756800
2.0 2005.224490 707.122449 5.074237
3.0 2934.673913 1030.413043 5.572013
4.0 2739.956522 964.291925 5.196055
5.0 2456.979899 826.768844 4.732460
median_house_value
housing_median_age
1.0 190250.000000
2.0 229438.836735
3.0 239450.043478
4.0 230054.105590
5.0 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()
Copy
	
longitude latitude \
min max mean min max mean
housing_median_age
1.0 -122.00 -120.93 -121.465000 37.65 38.23 37.940000
2.0 -122.51 -115.80 -119.035306 33.16 40.58 35.410816
3.0 -122.33 -115.60 -118.798478 32.87 38.77 35.164783
4.0 -122.72 -116.76 -118.805093 32.65 39.00 34.987764
5.0 -122.55 -115.55 -118.789497 32.55 40.60 35.095327
total_rooms total_bedrooms ... \
min max mean min ...
housing_median_age ...
1.0 2062.0 2254.0 2158.000000 328.0 ...
2.0 96.0 21897.0 5237.102041 18.0 ...
3.0 475.0 21060.0 6920.326087 115.0 ...
4.0 2.0 37937.0 6065.614907 2.0 ...
5.0 111.0 25187.0 4926.261307 21.0 ...
population households median_income \
mean min max mean min
housing_median_age
1.0 637.000000 112.0 268.0 190.000000 4.2500
2.0 2005.224490 16.0 2873.0 707.122449 1.9667
3.0 2934.673913 123.0 3112.0 1030.413043 2.1187
4.0 2739.956522 2.0 5189.0 964.291925 0.5360
5.0 2456.979899 20.0 3886.0 826.768844 0.7526
median_house_value \
max mean min max
housing_median_age
1.0 5.2636 4.756800 189200.0 191300.0
2.0 10.1531 5.074237 47500.0 500001.0
3.0 11.5199 5.572013 83200.0 500001.0
4.0 13.4883 5.196055 42500.0 500001.0
5.0 12.6320 4.732460 50000.0 500001.0
mean
housing_median_age
1.0 190250.000000
2.0 229438.836735
3.0 239450.043478
4.0 230054.105590
5.0 211035.708543
[5 rows x 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()
Copy
	
total_rooms total_bedrooms \
min max mean min max
housing_median_age
1.0 2062.0 2254.0 2158.000000 328.0 343.0
2.0 96.0 21897.0 5237.102041 18.0 3513.0
3.0 475.0 21060.0 6920.326087 115.0 3559.0
4.0 2.0 37937.0 6065.614907 2.0 5471.0
5.0 111.0 25187.0 4926.261307 21.0 4386.0
mean median
housing_median_age
1.0 335.500000 335.5
2.0 871.448980 707.0
3.0 1190.826087 954.0
4.0 1068.192547 778.0
5.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()
Copy
	
longitude latitude total_rooms \
housing_median_age total_bedrooms
1.0 328.0 -120.93 37.65 2254.0
343.0 -122.00 38.23 2062.0
2.0 18.0 -115.80 33.26 96.0
35.0 -121.93 37.78 227.0
55.0 -117.27 33.93 337.0
... ... ... ...
52.0 1360.0 -118.35 34.06 3446.0
1535.0 -122.41 37.80 3260.0
1944.0 -118.25 34.05 2806.0
2509.0 -122.41 37.79 6016.0
2747.0 -122.41 37.79 5783.0
population households median_income \
housing_median_age total_bedrooms
1.0 328.0 402.0 112.0 4.2500
343.0 872.0 268.0 5.2636
2.0 18.0 30.0 16.0 5.3374
35.0 114.0 49.0 3.1591
55.0 115.0 49.0 3.1042
... ... ... ...
52.0 1360.0 1768.0 1245.0 2.4722
1535.0 3260.0 1457.0 0.9000
1944.0 2232.0 1605.0 0.6775
2509.0 3436.0 2119.0 2.5166
2747.0 4518.0 2538.0 1.7240
median_house_value
housing_median_age total_bedrooms
1.0 328.0 189200.0
343.0 191300.0
2.0 18.0 47500.0
35.0 434700.0
55.0 164800.0
... ...
52.0 1360.0 500001.0
1535.0 500001.0
1944.0 350000.0
2509.0 275000.0
2747.0 225000.0
[13394 rows x 7 columns]

17. Gráficoslink image 183

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 184

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()
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5666b9990>
	
<Figure size 432x288 with 1 Axes>

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()
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5663ce610>
	
<Figure size 432x288 with 1 Axes>

17.2. Diagrama de barras verticaislink image 185

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()
Copy
	
<Figure size 432x288 with 1 Axes>

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

	
dataframe.plot.bar(stacked=True)
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc56265c5d0>
	
<Figure size 432x288 with 1 Axes>

17.3. Diagrama de barras horizontallink image 186

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

	
dataframe.plot.barh()
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc56247fa10>
	
<Figure size 432x288 with 1 Axes>

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

	
dataframe.plot.barh(stacked=True)
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc562d1d2d0>
	
<Figure size 432x288 with 1 Axes>

17.4. Histogramalink image 187

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)
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5650711d0>
	
<Figure size 432x288 with 1 Axes>

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

	
dataframe.plot.hist(alpha=0.5, stacked=True)
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc5625779d0>
	
<Figure size 432x288 with 1 Axes>

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)
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc562324990>
	
<Figure size 432x288 with 1 Axes>

17.5. Diagramas de Velaslink image 188

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()
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc56201a410>
	
<Figure size 432x288 with 1 Axes>

17.6. Gráficos de áreaslink image 189

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

	
dataframe.plot.area()
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc561e9ca50>
	
<Figure size 432x288 with 1 Axes>

17.7. Diagrama de dispersãolink image 190

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')
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc561e2ff10>
	
<Figure size 432x288 with 1 Axes>

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

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)
Copy
	
<matplotlib.axes._subplots.AxesSubplot at 0x7fc561cdded0>
	
<Figure size 432x288 with 2 Axes>

Continuar lendo

Últimos posts -->

Você viu esses projetos?

Horeca chatbot

Horeca chatbot Horeca chatbot
Python
LangChain
PostgreSQL
PGVector
React
Kubernetes
Docker
GitHub Actions

Chatbot conversacional para cozinheiros de hotéis e restaurantes. Um cozinheiro, gerente de cozinha ou serviço de quarto de um hotel ou restaurante pode falar com o chatbot para obter informações sobre receitas e menus. Mas também implementa agentes, com os quais pode editar ou criar novas receitas ou menus

Naviground

Naviground Naviground

Subtify

Subtify Subtify
Python
Whisper
Spaces

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 -->