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 是一个广泛使用的 Python 数据分析工具包。 由于它使用 fsspec 来读写远程数据,因此您可以使用 Hugging Face 路径(hf://)来读写 Hub 上的数据。

加载 DataFrame

您可以从本地文件或 Hugging Face Datasets 等远程存储中加载数据。Pandas 支持多种格式,包括 CSV、JSON 和 Parquet:

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

要从 Hugging Face 加载文件,路径必须以 hf:// 开头。例如,stanfordnlp/imdb 数据集仓库的路径为 hf://datasets/stanfordnlp/imdb。Hugging Face 上的该数据集包含多个 Parquet 文件。Parquet 文件格式旨在高效地读写数据帧,并便于在不同数据分析语言之间共享数据。以下是如何加载文件 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

有关 Hugging Face 路径及其实现方式的更多信息,请参阅 HfFileSystem 的客户端库文档。

相同的 hf:// 路径也适用于 Storage Buckets:

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

保存 DataFrame

您可以使用 to_csv/to_json/to_parquet 将 pandas DataFrame 保存到本地文件或 Hugging Face。

要将 DataFrame 保存到 Hugging Face,您首先需要使用您的 Hugging Face 账户登录,例如使用:

hf auth login

然后,您可以创建数据集仓库,例如使用:

from huggingface_hub import HfApi

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

最后,你可以在 Pandas 中使用 Hugging Face 路径:

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

请注意,Hugging Face 上的 Parquet 文件经过优化,以提升存储效率、加快下载和上传速度,并支持高效的数据集流式处理和编辑:

  • Parquet 内容定义分块针对 Hugging Face 的存储后端 Xet 优化了 Parquet。它通过基于分块的重复数据删除加速了上传和下载,并支持高效的文件编辑
  • Page index 在流式传输时加速过滤,并支持高效的随机访问,例如在 Dataset Viewer 中。

Pandas 需要额外的参数来写入优化的 Parquet 文件:

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 以启用 Parquet Content Defined Chunking,用于去重和编辑(需要pyarrow>=21.0)
  • write_page_index=True 以在 Parquet 元数据中包含页面索引,用于流式处理和随机访问

内容定义分块(CDC)使 Parquet 写入器以特定方式对数据页进行分块,从而确保重复数据被分块并以相同方式压缩。 如果没有 CDC,数据页会被任意分块,因此由于压缩的存在,无法检测出重复数据。 得益于 CDC,从 Hugging Face 上传和下载 Parquet 文件的速度更快,因为重复数据只需上传或下载一次。

有关 Xet 的更多信息,请参见此处。

利用 Xet 去重功能处理 Parquet

经过优化的 Parquet 文件采用 Content Defined Chunking 进行写入,从而实现去重。 这加快了上传速度,因为 Hugging Face 上已存在的数据块无需再次上传,从而大幅节省了 I/O。

例如,此代码上传 df 的内容,然后对于 edited_df,由于只上传了发生变化的块,因此上传速度更快:

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

数据块大小约为 64kB,而 Parquet 按列存储数据,因此实际编辑优化后的 Parquet 文件时,会发生以下情况:

  • 添加新列 -> 仅上传新列的块
  • 添加/编辑/删除一行 -> 每列上传一个数据块

此外,包含元数据的 Parquet 文件尾块也会被上传。

使用图像

您可以加载一个包含元数据文件的文件夹,该文件中有一个字段用于存储图像的名称或路径,其结构如下:

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

您可以按以下方式迭代图像路径:

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"]):
    ...

由于数据集采用受支持的结构(即包含file_name字段的metadata.csv或.jsonl文件),您可以将该数据集保存到 Hugging Face,Dataset Viewer 将在 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",
)

图像方法与 Parquet

使用 pandas-image-methods 后,你可以在图像列上启用 PIL.Image 方法。它还可以将数据集保存为一个单独的 Parquet 文件,其中同时包含图像和元数据:

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

所有 PIL.Image 方法均可用,例如

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

使用 Audios

您可以加载一个包含元数据文件的文件夹,该文件中有一个字段用于存储音频的名称或路径,其结构如下:

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

您可以像这样迭代音频路径:

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"]):
    ...

由于数据集采用受支持的结构(即包含file_name字段的metadata.csv或.jsonl文件),您可以将其保存到 Hugging Face,Hub 数据集查看器将同时显示元数据和音频。

from huggingface_hub import HfApi
api = HfApi()

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

音频方法与 Parquet

使用 pandas-audio-methods 后,你可以在音频列上启用 soundfile 方法。它还支持将数据集保存为一个包含音频和元数据的单个 Parquet 文件:

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

这使得它易于与 librosa 配合使用,例如用于重采样:

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

使用 Transformers

您可以使用 transformers 流水线在 pandas DataFrame 上执行分类、文本生成、图像生成等任务。 本节展示了一些使用 tqdm 显示进度条的示例。

Pipelines 不接受 tqdm 对象作为输入,但你可以使用 Python 生成器,形式为 x for x in tqdm(...)

文本分类

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

文本生成

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