Introdução
Este laboratório foca em como escalar a análise de dados para conjuntos de dados maiores usando pandas. Ele cobre métodos como carregar menos dados, usar tipos de dados eficientes, chunking (fragmentação) e alavancar outras bibliotecas como Dask. É importante notar que pandas é mais adequado para análise na memória (in-memory analytics) e pode não ser a melhor ferramenta para conjuntos de dados muito grandes.
Dicas da VM
Após a inicialização da VM, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.
Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.
Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão, e resolveremos o problema prontamente para você.
Gerar Conjunto de Dados
O primeiro passo é gerar um grande conjunto de dados para teste. Criamos um conjunto de dados com muitas colunas que podem ser armazenadas em um arquivo parquet. Este passo requer as bibliotecas pandas e numpy.
import pandas as pd
import numpy as np
def make_timeseries(start="2000-01-01", end="2000-12-31", freq="1D", seed=None):
## Function to generate timeseries data
index = pd.date_range(start=start, end=end, freq=freq, name="timestamp")
n = len(index)
state = np.random.RandomState(seed)
columns = {
"name": state.choice(["Alice", "Bob", "Charlie"], size=n),
"id": state.poisson(1000, size=n),
"x": state.rand(n) * 2 - 1,
"y": state.rand(n) * 2 - 1,
}
df = pd.DataFrame(columns, index=index, columns=sorted(columns))
if df.index[-1] == end:
df = df.iloc[:-1]
return df
timeseries = [
make_timeseries(freq="1T", seed=i).rename(columns=lambda x: f"{x}_{i}")
for i in range(10)
]
ts_wide = pd.concat(timeseries, axis=1)
ts_wide.to_parquet("timeseries_wide.parquet")
Carregar Menos Dados
Em vez de carregar todos os dados, podemos carregar apenas as colunas que precisamos. Aqui, demonstramos dois métodos para carregar menos dados do arquivo parquet.
## Option 1: Load all data then filter
columns = ["id_0", "name_0", "x_0", "y_0"]
pd.read_parquet("timeseries_wide.parquet")[columns]
## Option 2: Load only the requested columns
pd.read_parquet("timeseries_wide.parquet", columns=columns)
Usar Tipos de Dados Eficientes
Os tipos de dados padrão do Pandas não são os mais eficientes em termos de memória. Este passo mostra como usar tipos de dados mais eficientes para armazenar conjuntos de dados maiores na memória.
ts = make_timeseries(freq="30S", seed=0)
ts.to_parquet("timeseries.parquet")
ts = pd.read_parquet("timeseries.parquet")
## Convert 'name' column to 'category' type for efficiency
ts2 = ts.copy()
ts2["name"] = ts2["name"].astype("category")
## Downcast numeric columns to their smallest types
ts2["id"] = pd.to_numeric(ts2["id"], downcast="unsigned")
ts2[["x", "y"]] = ts2[["x", "y"]].apply(pd.to_numeric, downcast="float")
Usar Chunking (Fragmentação)
Chunking (fragmentação) é um método para dividir um problema grande em problemas menores que podem ser resolvidos independentemente. Contanto que cada chunk (fragmento) caiba na memória, você pode trabalhar com conjuntos de dados que são muito maiores do que a memória.
files = pathlib.Path("data/timeseries/").glob("ts*.parquet")
counts = pd.Series(dtype=int)
for path in files:
df = pd.read_parquet(path)
counts = counts.add(df["name"].value_counts(), fill_value=0)
counts.astype(int)
Usar Outras Bibliotecas
Outras bibliotecas como Dask podem lidar com conjuntos de dados maiores do que a memória. Dask fornece uma API semelhante ao pandas e pode processar dados em paralelo.
import dask.dataframe as dd
ddf = dd.read_parquet("data/timeseries/ts*.parquet", engine="pyarrow")
## Compute value counts using Dask
ddf["name"].value_counts().compute()
Resumo
Neste laboratório, demonstramos diferentes técnicas para escalar a análise de dados para conjuntos de dados maiores usando pandas. Geramos um grande conjunto de dados, aprendemos como carregar menos dados, usar tipos de dados eficientes e chunking (fragmentação). Também exploramos como aproveitar outras bibliotecas como Dask para lidar com conjuntos de dados maiores do que a memória. As técnicas e conceitos aprendidos neste laboratório serão úteis ao lidar com grandes conjuntos de dados em projetos de análise de dados.