Hub documentation

Pandas

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Pandas

Pandas es un kit de herramientas de análisis de datos de Python muy utilizado. Dado que utiliza fsspec para leer y escribir datos remotos, puedes usar las rutas de Hugging Face (hf://) para leer y escribir datos en el Hub.

Cargar un DataFrame

Puedes cargar datos desde archivos locales o desde almacenamiento remoto como Hugging Face Datasets. Pandas admite muchos formatos, incluidos CSV, JSON y Parquet:

>>> import pandas as pd
>>> df = pd.read_csv("path/to/data.csv")

Para cargar un archivo de Hugging Face, la ruta debe comenzar con hf://. Por ejemplo, la ruta al repositorio del conjunto de datos stanfordnlp/imdb es hf://datasets/stanfordnlp/imdb. El conjunto de datos en Hugging Face contiene múltiples archivos Parquet. El formato de archivo Parquet está diseñado para hacer eficiente la lectura y escritura de data frames, y para facilitar el intercambio de datos entre lenguajes de análisis de datos. A continuación se muestra cómo cargar el archivo plain_text/train-00000-of-00001.parquet:

>>> import pandas as pd
>>> df = pd.read_parquet("hf://datasets/stanfordnlp/imdb/plain_text/train-00000-of-00001.parquet")
>>> df
                                                    text  label
0      I rented I AM CURIOUS-YELLOW from my video sto...      0
1      "I Am Curious: Yellow" is a risible and preten...      0
2      If only to avoid making this type of film in t...      0
3      This film was probably inspired by Godard's Ma...      0
4      Oh, brother...after hearing about this ridicul...      0
...                                                  ...    ...
24995  A hit at the time but now better categorised a...      1
24996  I love this movie like no other. Another time ...      1
24997  This film and it's sequel Barry Mckenzie holds...      1
24998  'The Adventures Of Barry McKenzie' started lif...      1
24999  The story centers around Barry McKenzie who mu...      1

Para obtener más información sobre las rutas de Hugging Face y cómo se implementan, consulte la documentación de la biblioteca de cliente sobre HfFileSystem.

Las mismas rutas hf:// también funcionan con Storage Buckets:

>>> df = pd.read_parquet("hf://buckets/username/my-bucket/data.parquet")
>>> df.to_parquet("hf://buckets/username/my-bucket/output.parquet")

Guardar un DataFrame

Puedes guardar un DataFrame de pandas usando to_csv/to_json/to_parquet en un archivo local o directamente en Hugging Face.

Para guardar el DataFrame en Hugging Face, primero necesitas iniciar sesión con tu cuenta de Hugging Face, por ejemplo, usando:

hf auth login

Luego puedes crear un repositorio de datos, por ejemplo, usando:

from huggingface_hub import HfApi

HfApi().create_repo(repo_id="username/my_dataset", repo_type="dataset")

Finalmente, puedes usar rutas de Hugging Face en Pandas:

import pandas as pd

df.to_parquet("hf://datasets/username/my_dataset/imdb.parquet")

# or write in separate files if the dataset has train/validation/test splits
df_train.to_parquet("hf://datasets/username/my_dataset/train.parquet")
df_valid.to_parquet("hf://datasets/username/my_dataset/validation.parquet")
df_test .to_parquet("hf://datasets/username/my_dataset/test.parquet")

Tenga en cuenta que los archivos Parquet en Hugging Face están optimizados para mejorar la eficiencia del almacenamiento, acelerar las descargas y subidas, y permitir la transmisión y edición eficientes de conjuntos de datos:

  • El Parquet Content Defined Chunking optimiza Parquet para Xet, el backend de almacenamiento de Hugging Face. Acelera las cargas y descargas gracias a la deduplicación basada en fragmentos y permite editar archivos de manera eficiente
  • El índice de páginas acelera los filtros durante la transmisión y permite un acceso aleatorio eficiente, por ejemplo, en el Dataset Viewer

Pandas requiere un argumento adicional para escribir archivos Parquet optimizados:

import pandas as pd

df.to_parquet(
    "hf://datasets/username/my_dataset/imdb.parquet",
    # Optimize for Xet
    use_content_defined_chunking=True,
    write_page_index=True,
)
  • use_content_defined_chunking=True para habilitar Parquet Content Defined Chunking, para deduplicación y edición (requiere pyarrow>=21.0)
  • write_page_index=True para incluir un índice de páginas en los metadatos de Parquet, para streaming y acceso aleatorio

El chunking definido por contenido (CDC) permite que el escritor de Parquet divida las páginas de datos de manera que los datos duplicados se agrupen y compriman de forma idéntica. Sin CDC, las páginas se dividen de forma arbitraria y, por lo tanto, es imposible detectar los datos duplicados debido a la compresión. Gracias al CDC, las cargas y descargas de Parquet desde Hugging Face son más rápidas, ya que los datos duplicados se cargan o descargan solo una vez.

Encuentra más información sobre Xet aquí.

Aprovecha la deduplicación de Xet para Parquet

Los archivos Parquet optimizados se escriben con Content Defined Chunking, lo que permite la deduplicación. Esto acelera las cargas, ya que los fragmentos de datos que ya existen en Hugging Face no necesitan volver a subirse, lo que ahorra una gran cantidad de E/S.

Por ejemplo, este código sube el contenido de df y luego, para edited_df, la subida es más rápida ya que solo sube los fragmentos que cambiaron:

import pandas as pd

df.to_parquet(
    "hf://datasets/username/my_dataset/imdb.parquet",
    # Optimize for Xet
    use_content_defined_chunking=True,
    write_page_index=True,
)

edited_df = ...  # e.g. with added/modified/removed rows or columns

edited_df.to_parquet(
    "hf://datasets/username/my_dataset/imdb.parquet",
    # Optimize for Xet
    use_content_defined_chunking=True,
    write_page_index=True,
)

Los fragmentos son de ~64 kB y Parquet guarda los datos columna por columna, por lo que en la práctica esto es lo que ocurre al editar un archivo Parquet optimizado:

  • agregar una nueva columna -> solo se suben los fragmentos de la nueva columna
  • agregar/editar/eliminar una fila -> se sube un fragmento por columna

Y además de esto, también se suben los fragmentos del pie de página de Parquet que contienen metadatos.

Usar imágenes

Puedes cargar una carpeta con un archivo de metadatos que contenga un campo para los nombres o las rutas de las imágenes, estructurado de la siguiente manera:

Example 1:            Example 2:
folder/               folder/
├── metadata.csv      ├── metadata.csv
├── img000.png        └── images
├── img001.png            ├── img000.png
...                       ...
└── imgNNN.png            └── imgNNN.png

Puedes iterar sobre las rutas de las imágenes de esta manera:

import pandas as pd

folder_path = "path/to/folder/"
df = pd.read_csv(folder_path + "metadata.csv")
for image_path in (folder_path + df["file_name"]):
    ...

Dado que el conjunto de datos tiene una estructura compatible (un archivo metadata.csv o .jsonl con un campo file_name), puedes guardar este conjunto de datos en Hugging Face y el Dataset Viewer mostrará tanto los metadatos como las imágenes en Hugging Face.

from huggingface_hub import HfApi
api = HfApi()

api.upload_folder(
    folder_path=folder_path,
    repo_id="username/my_image_dataset",
    repo_type="dataset",
)

Métodos de imagen y Parquet

Al usar pandas-image-methods se habilitan los métodos de PIL.Image en una columna de imágenes. También permite guardar el conjunto de datos como un único archivo Parquet que contiene tanto las imágenes como los metadatos:

import pandas as pd
from pandas_image_methods import PILMethods

pd.api.extensions.register_series_accessor("pil")(PILMethods)

df["image"] = (folder_path + df["file_name"]).pil.open()
df.to_parquet("data.parquet")

Todos los métodos de PIL.Image están disponibles, por ejemplo:

df["image"] = df["image"].pil.rotate(90)

Usar audios

Puede cargar una carpeta con un archivo de metadatos que contenga un campo para los nombres o rutas de los audios, estructurado de la siguiente manera:

Example 1:            Example 2:
folder/               folder/
├── metadata.csv      ├── metadata.csv
├── rec000.wav        └── audios
├── rec001.wav            ├── rec000.wav
...                       ...
└── recNNN.wav            └── recNNN.wav

Puedes iterar sobre las rutas de los audios de esta manera:

import pandas as pd

folder_path = "path/to/folder/"
df = pd.read_csv(folder_path + "metadata.csv")
for audio_path in (folder_path + df["file_name"]):
    ...

Dado que el conjunto de datos tiene una estructura compatible (un archivo metadata.csv o .jsonl con un campo file_name), puedes guardarlo en Hugging Face y el visor de conjuntos de datos del Hub mostrará tanto los metadatos como el audio.

from huggingface_hub import HfApi
api = HfApi()

api.upload_folder(
    folder_path=folder_path,
    repo_id="username/my_audio_dataset",
    repo_type="dataset",
)

Métodos de audio y Parquet

Al usar pandas-audio-methods se habilitan los métodos de soundfile en una columna de audio. También permite guardar el dataset como un único archivo Parquet que contiene tanto los audios como los metadatos:

import pandas as pd
from pandas_audio_methods import SFMethods

pd.api.extensions.register_series_accessor("sf")(SFMethods)

df["audio"] = (folder_path + df["file_name"]).sf.open()
df.to_parquet("data.parquet")

Esto facilita su uso con librosa, por ejemplo, para el re-muestreo:

df["audio"] = [librosa.load(audio, sr=16_000) for audio in df["audio"]]
df["audio"] = df["audio"].sf.write()

Usar Transformers

Puedes usar pipelines de transformers en DataFrames de pandas para clasificar, generar texto, imágenes, etc. Esta sección muestra algunos ejemplos con tqdm para barras de progreso.

Los pipelines no aceptan un objeto tqdm como entrada, pero puedes usar un generador de Python en su lugar, en la forma x for x in tqdm(...)

Clasificación de texto

from transformers import pipeline
from tqdm import tqdm

pipe = pipeline("text-classification", model="clapAI/modernBERT-base-multilingual-sentiment")

# Compute labels
df["label"] = [y["label"] for y in pipe(x for x in tqdm(df["text"]))]
# Compute labels and scores
df[["label", "score"]] = [(y["label"], y["score"]) for y in pipe(x for x in tqdm(df["text"]))]

Generación de texto

from transformers import pipeline
from tqdm import tqdm

pipe = pipeline("text-generation", model="Qwen/Qwen2.5-1.5B-Instruct")

# Generate chat response
prompt = "What is the main topic of this sentence ? REPLY IN LESS THAN 3 WORDS. Sentence: '{}'"
df["output"] = [y["generated_text"][1]["content"] for y in pipe([{"role": "user", "content": prompt.format(x)}] for x in tqdm(df["text"]))]
Update on GitHub