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 に直接保存できます。

Hugging Face に DataFrame を保存するには、まず 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 Content Defined Chunking は、Hugging Face のストレージバックエンドである Xet 向けに Parquet を最適化します。チャンクベースの重複排除によりアップロードとダウンロードが高速化され、効率的なファイル編集が可能になります。
  • ページインデックスはストリーミング時のフィルタリングを高速化し、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 メタデータにページインデックスが含まれます。

Content defined chunking (CDC) により、Parquet writer は重複するデータを同一にチャンク化・圧縮できるように、データページをチャンク化します。 CDC を使用しない場合、ページは任意にチャンク化されるため、圧縮の影響により重複データの検出が不可能になります。 CDC により、重複データは一度だけアップロードまたはダウンロードされるため、Hugging Face への Parquet のアップロードとダウンロードが高速化されます。

Xetの詳細については、こちらをご覧ください。

Parquet での Xet の重複排除を活用

最適化された 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はカラムごとにデータを保存するため、Optimized Parquetファイルを編集する際に実際に起こることは以下の通りです。

  • 新しい列を追加 -> 新しい列のチャンクのみがアップロードされます
  • 行の追加/編集/削除 -> 各カラムごとに1つのチャンクがアップロードされます

さらに、メタデータを含む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 Dataset Viewer でメタデータとオーディオの両方が表示されます。

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オブジェクトを入力として受け取りませんが、代わりにx for x in tqdm(...)のような形式のPythonジェネレーターを使用できます。

テキスト分類

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