Búsqueda de sitios web

Consejos para manejar grandes conjuntos de datos en Python


Trabajar con grandes conjuntos de datos es común pero desafiante. A continuación se ofrecen algunos consejos para simplificar el trabajo con conjuntos de datos tan grandes en Python.

Manejar grandes conjuntos de datos en Python puede ser un verdadero desafío, especialmente cuando estás acostumbrado a trabajar con conjuntos de datos más pequeños que tu computadora puede manejar fácilmente. ¡Pero no temas! Python está repleto de herramientas y trucos que le ayudarán a procesar y analizar big data de forma eficiente.

En este tutorial, le explicaré consejos esenciales para procesar grandes conjuntos de datos como un profesional centrándome en:

  • Funciones principales de Python: generadores y multiprocesamiento
  • Procesamiento fragmentado de grandes conjuntos de datos en pandas
  • Usando Dask para computación paralela
  • Usando PySpark para computación distribuida

¡Empecemos!

Nota: Esta es una guía breve que cubre consejos útiles y no se centra en un conjunto de datos específico. Pero puede utilizar conjuntos de datos como el conjunto de datos de Bank Marketing o los datos de registros de viajes de The NYC TLC. Usaremos nombres de archivos genéricos como large_dataset.csv en los ejemplos de código.

1. Utilice generadores en lugar de listas

Al procesar grandes conjuntos de datos, suele resultar tentador cargar todo en una lista. Pero esto suele consumir una gran cantidad de memoria. Los generadores, por otro lado, generan datos sólo cuando son necesarios (sobre la marcha), lo que hace que la tarea sea más eficiente en cuanto a memoria.

Supongamos que tiene un archivo de registro de gran tamaño (registros del servidor o datos de actividad del usuario) y necesita analizarlo línea por línea. Con un generador, puede leer y procesar el contenido (una línea a la vez) sin cargar todo el archivo en la memoria.

def read_large_file(file_name):
    with open(file_name, 'r') as file:
        for line in file:
            yield line  

El uso de una función generadora devuelve un objeto generador y no una lista. Puede recorrer este generador y procesar cada línea individualmente.

2. Vaya en paralelo con el multiprocesamiento

El procesamiento de grandes conjuntos de datos puede resultar lento si está limitado a un único núcleo de procesador. El módulo de multiprocesamiento de Python le permite dividir tareas en varios núcleos de CPU. Esto acelera las cosas significativamente.

Supongamos que tiene un conjunto de datos masivo con precios de la vivienda y desea eliminar valores atípicos y normalizar los datos. Con el multiprocesamiento, puede manejar esta tarea en partes paralelas para reducir el tiempo de procesamiento.

import pandas as pd
import numpy as np
from multiprocessing import Pool

# Function to clean and normalize data for each chunk
def clean_and_normalize(df_chunk):
    # Remove top 5% as outliers in the 'price' column
    df_chunk = df_chunk[df_chunk['price'] < df_chunk['price'].quantile(0.95)]
    
    # Normalize the 'price' column
    df_chunk['price'] = (df_chunk['price'] - df_chunk['price'].min()) / (df_chunk['price'].max() - df_chunk['price'].min())
    return df_chunk

# Function to read data in chunks and process it in parallel
def process_in_chunks(file_name, chunk_size):
    chunks = pd.read_csv(file_name, chunksize=chunk_size)
    
    with Pool(4) as pool:  # Adjust the number of processes for your CPU
        # Process each chunk in parallel and combine results
        cleaned_data = pd.concat(pool.map(clean_and_normalize, chunks))
    
    return cleaned_data

if __name__ == "__main__":
    cleaned_df = process_in_chunks('large_house_data.csv', chunk_size=100000)
    print(cleaned_df.head())

En cada fragmento, filtramos los valores atípicos de alto precio y luego normalizamos la columna de precios. Usando Pool(4), creamos cuatro procesos para manejar fragmentos separados al mismo tiempo, acelerando la limpieza y la normalización. Con varios núcleos trabajando en fragmentos, el procesamiento es mucho más rápido.

3. Utilice el tamaño de fragmentos de Pandas para el procesamiento fragmentado

Pandas es excelente para la manipulación del análisis de datos, pero cargar un conjunto de datos masivo en un DataFrame puede ejercer presión sobre su memoria. Afortunadamente, el parámetro chunksize en pd.read_csv() le permite procesar grandes conjuntos de datos en partes manejables o "fragmentos".

Supongamos que está trabajando con datos de ventas y desea calcular las ventas totales. Usando chunksize, puede leer y resumir los valores de ventas fragmento por fragmento.

import pandas as pd

total_sales = 0
chunk_size = 100000  # Define chunk size to read data in batches

# Load data in chunks and process each chunk
for chunk in pd.read_csv('large_sales_data.csv', chunksize=chunk_size):
    total_sales += chunk['sales'].sum()  # Summing up sales column in each chunk

print(f"Total Sales: {total_sales}")

Cada fragmento se carga y procesa de forma independiente, lo que le permite trabajar con archivos enormes sin consumir memoria. Sumamos las ventas en cada porción, aumentando gradualmente el total. Sólo una parte del archivo está en la memoria en cualquier momento, por lo que puedes manejar archivos muy grandes sin problemas.

4. Utilice Dask para computación paralela

Si se siente cómodo con Pandas pero necesita más potencia, Dask ofrece un siguiente paso conveniente con la computación paralela. El marco de datos de Dask utiliza pandas bajo el capó. Así que te pondrás al día con Dask rápidamente si ya te sientes cómodo con los pandas.

También puede utilizar Dask junto con bibliotecas como Scikit-learn y XGBoost para entrenar modelos de aprendizaje automático en grandes conjuntos de datos. Puedes instalar Dask con pip.

Supongamos que desea calcular las ventas promedio por categoría en un conjunto de datos enorme. He aquí un ejemplo:

import dask.dataframe as dd

# Load data into a Dask DataFrame
df = dd.read_csv('large_sales_data.csv')

# Group by 'category' and calculate mean sales (executed in parallel)
mean_sales = df.groupby('category')['sales'].mean().compute()

print(mean_sales)

Entonces, si está acostumbrado a la sintaxis de Pandas, Dask le resulta familiar pero puede manejar mejor conjuntos de datos mucho más grandes.

5. Considere PySpark para el procesamiento de Big Data

Para conjuntos de datos realmente grandes (piense en cientos de gigabytes o más), puede utilizar PySpark. PySpark está diseñado para manejar datos distribuidos en clústeres, adecuado para el procesamiento masivo de datos.

Supongamos que está trabajando con un conjunto de datos que contiene millones de calificaciones de películas y le gustaría encontrar la calificación promedio para cada género.

from pyspark.sql import SparkSession

# Start a Spark session
spark = SparkSession.builder.appName("MovieRatings").getOrCreate()

# Load the dataset into a Spark DataFrame
df = spark.read.csv('movie_ratings.csv', header=True, inferSchema=True)

# Perform transformations (e.g., group by genre and calculate average rating)
df_grouped = df.groupBy('genre').mean('rating')

# Show the result
df_grouped.show()

PySpark distribuye datos y computación entre múltiples máquinas o núcleos.

Concluyendo

Manejar grandes conjuntos de datos en Python es mucho más manejable con las herramientas adecuadas. Aquí hay un resumen rápido:

  • Generadores para procesar datos con eficiencia de memoria.
  • El multiprocesamiento le permite dividir el trabajo entre núcleos de CPU para un procesamiento más rápido
  • Utilice el tamaño de fragmentos en pandas para cargar datos en fragmentos para un procesamiento eficiente en la memoria
  • Dask, una biblioteca tipo pandas para computación paralela, excelente para grandes conjuntos de datos
  • PySpark para procesamiento distribuido de big data

¡Feliz codificación!