DS DevShelfHub Projects · AI tools
Cheatsheets / HuggingFace Datasets
Cheatsheet · AI frameworks

HuggingFace Datasets: load_dataset, map, filter and Streaming Reference Guide

By DevShelfHub

load_dataset, map, filter, splits, streaming, Arrow/Parquet, push_to_hub, audio/image features — the Datasets library as a one-page reference.

108 items 8 min Arrow Streaming Map

Start hereQuick start · 6 you’ll reach for daily

Loadload_dataset("imdb")
Transformds.map(fn, batched=True)
Filterds.filter(lambda x: …)
Splitds.train_test_split(test_size=0.2)
Streamload_dataset(…, streaming=True)
Pushds.push_to_hub("my-org/name")

Target versions · paceVersions

Targets: datasets ≥ 3.0 huggingface_hub ≥ 0.24 pyarrow (bundled) python ≥ 3.9

Backed by Apache Arrow on disk — that’s why loads are zero-copy and memory-mapped. Dataset has random access; IterableDataset (streaming mode) doesn’t. The Hub CLI moved from huggingface-cli to hf in huggingface_hub ≥ 0.24 — both still work, hf is the new one.

Install · envSetup

bash
# Core
pip install datasets                # ≥ 3.0

# Optional extras — install what you need
pip install "datasets[audio]"       # soundfile + librosa + torchcodec
pip install "datasets[vision]"      # Pillow + image features
pip install "datasets[s3]"          # s3fs for cloud-backed paths

# To upload to the Hub
pip install huggingface_hub
hf auth login                       # paste a token from huggingface.co/settings/tokens

# Optional speed-ups
pip install pyarrow                 # bundled, but pin if you need a version

Where things liveCommon imports

from datasets import load_datasetThe 90% entry point. Reads from Hub, files, or builders.
from datasets import Dataset, DatasetDict, IterableDataset, IterableDatasetDictCore classes. DatasetDict = splits wrapper.
from datasets import Features, Value, ClassLabel, SequenceSchema primitives.
from datasets import Audio, Image, VideoMedia features — auto-decode on read.
from datasets import concatenate_datasets, interleave_datasetsConcat (stack) or interleave (mix) splits.
from datasets import load_from_diskReload a dataset saved with save_to_disk.
from huggingface_hub import loginProgrammatic auth. Or just run hf auth login.

From Hub · from filesLoading

From the Hub

load_dataset("imdb")Repo on hub. Returns a DatasetDict with all splits.
load_dataset("imdb", split="train")Single split as a Dataset.
load_dataset("imdb", split="train[:1%]")Slice syntax. Great for prototyping.
load_dataset("glue", "sst2")Multi-config datasets need a config name.
load_dataset("imdb", revision="main")Pin a git revision. Reproducibility.
load_dataset(…, token=…)Private dataset. Or use hf auth login.

From local / remote files

load_dataset("csv", data_files="data.csv")CSV loader. Same for json, parquet, text, arrow.
load_dataset("json", data_files={"train":"t.jsonl","test":"v.jsonl"})Dict maps file paths to splits.
load_dataset("parquet", data_files="s3://bucket/….parquet")Cloud paths work directly (with the s3 extra).
load_dataset("imagefolder", data_dir="./images")Image classification: subfolder names = labels.
load_dataset("audiofolder", data_dir="./audio")Same idea for audio.
Dataset.from_dict({"x":[1,2], "y":[3,4]})Build a dataset from a Python dict / pandas / arrow.
Dataset.from_pandas(df)DataFrame → Dataset.
Dataset.from_generator(gen_fn)Generator function → Dataset (cached on disk).

Inspect

dsREPL shows features + num_rows per split.
ds.featuresSchema dict: column → type.
ds.column_names, ds.num_rows, ds.shapeQuick stats.
ds[0], ds[:5], ds["text"]Index by row, slice, or column name.
ds.info, ds.description, ds.citationProvenance from the dataset card.

Map · filter · selectTransformations

map & filter

ds.map(fn)Apply fn(example) -> dict to every row. New columns merge.
ds.map(fn, batched=True)Preferred fn(batch) -> dict. 10–100× faster for tokenizers.
ds.map(fn, batched=True, batch_size=1000, num_proc=4)Multi-process for CPU-bound transforms.
ds.map(fn, remove_columns=["text"])Drop columns after transform — saves disk.
ds.map(fn, with_indices=True)Pass row index to fn.
ds.filter(lambda x: x["label"] == 1)Keep matching rows. Supports batched=True.
ds.flatten()Expand nested struct columns into flat ones.

Reshape

ds.select([0,1,5,10])Pick rows by index list.
ds.shuffle(seed=42)Permute rows. Reproducible with seed.
ds.sort("label")In-place row sort by column.
ds.rename_column("old","new"), ds.rename_columns({…})Rename without copying data.
ds.remove_columns(["a","b"])Drop columns.
ds.cast_column("label", ClassLabel(names=[…]))Change a column’s type.
ds.cast(Features({…}))Re-cast whole schema.
ds.unique("label")Distinct values in a column. Useful for ClassLabel.

Worked example

python
from datasets import load_dataset
from transformers import AutoTokenizer

ds = load_dataset("imdb")
tok = AutoTokenizer.from_pretrained("bert-base-uncased")

# Batched map = orders of magnitude faster than per-example
def tokenize(batch: dict) -> dict:
    return tok(batch["text"], truncation=True, max_length=128)

encoded = ds.map(
    tokenize,
    batched=True,
    batch_size=1000,
    num_proc=4,                   # multi-process
    remove_columns=["text"],      # drop raw text once tokenized
    desc="Tokenizing",
)

# Cast labels to PyTorch tensors lazily
encoded = encoded.with_format("torch", columns=["input_ids", "attention_mask", "label"])
print(encoded["train"][0])

Train / val / testSplits & sampling

ds["train"], ds["test"]Index a DatasetDict by split name.
ds.train_test_split(test_size=0.2, seed=42)Split a single Dataset. Returns a DatasetDict.
ds.train_test_split(…, stratify_by_column="label")Stratified split. Preserves class balance.
load_dataset(…, split="train[:80%]")Slice syntax at load time. Avoids loading the whole split.
load_dataset(…, split="train[:80%]+train[90%:]")Concatenated slices.
concatenate_datasets([a, b])Vertical stack. Schemas must match.
interleave_datasets([a, b], probabilities=[0.7, 0.3])Mix datasets row-by-row. Great for training.
ds.class_encode_column("label")Auto-convert a string column to ClassLabel ints.

SchemaFeatures & types

Value("int32" | "string" | "float64" | …)Scalar columns. Arrow types.
ClassLabel(names=["neg","pos"])Integer-encoded categorical. Exposes .int2str / .str2int.
Sequence(Value("int32"))Variable-length list of a type.
Sequence({"x": Value("int32"), "y": Value("float32")})List of structs (e.g., bboxes).
Audio(sampling_rate=16_000)Audio column. Lazy decode to numpy.
Image(decode=True)Image column. Lazy decode to PIL.
Video()Video column — needs datasets[vision].
Translation(languages=["en","fr"])Parallel-text column.
ds.featuresRead the schema. Edit-by-copy via cast().

No download · one row at a timeStreaming

load_dataset(…, streaming=True)Returns an IterableDataset. No cache, no random access.
ds.take(n) / ds.skip(n)Bound a streaming dataset.
ds.shuffle(seed=42, buffer_size=10_000)Approximate shuffle in a fixed-size buffer.
ds.map(fn, batched=True)Lazy. Applied on-the-fly as you iterate.
ds.filter(fn)Same — lazy.
for row in ds: …Iterate in order. ds[0] doesn’t work.
ds.with_format("torch")PyTorch-tensor view. Plays well with DataLoader.
ds.batch(n)Convert streaming dataset into batched chunks.

Worked example

python
from datasets import load_dataset

# Streaming = no full download, no disk caching
ds = load_dataset(
    "HuggingFaceFW/fineweb",
    split="train",
    streaming=True,
)

ds = ds.shuffle(seed=42, buffer_size=10_000)   # approximate shuffle
ds = ds.filter(lambda x: len(x["text"]) > 200)
ds = ds.map(lambda x: {"chars": len(x["text"])})

# IterableDataset — iterate in order; no random access
for i, row in enumerate(ds.take(5)):
    print(i, row["chars"], row["text"][:80])

# Wrap for PyTorch DataLoader
from torch.utils.data import DataLoader
loader = DataLoader(ds.with_format("torch"), batch_size=32)

Tensors · DataFramesFormat

ds.with_format("torch")Read rows as PyTorch tensors. Non-destructive.
ds.with_format("torch", columns=["input_ids","label"])Only convert listed columns.
ds.with_format("tf")TensorFlow tensors.
ds.with_format("jax")JAX arrays.
ds.with_format("numpy")NumPy. Fastest for non-DL use cases.
ds.with_format("pandas")Slices return DataFrames.
ds.reset_format()Back to Python dicts.
ds.to_pandas(), ds.to_polars(), ds.to_dict()Materialize the whole thing (only when it fits in RAM).
ds.to_iterable_dataset(num_shards=64)Convert a Dataset to IterableDataset for distributed loading.

Disk · HubSave & share

ds.save_to_disk("./my_data")Persist a Dataset / DatasetDict locally.
load_from_disk("./my_data")Reload the saved dataset.
ds.to_parquet("out.parquet")Single-file parquet export.
ds.to_csv("out.csv"), ds.to_json("out.jsonl")Other dumps. CSV loses types — prefer parquet.
ds.push_to_hub("my-org/name")Upload to the Hub. Auth via hf auth login.
ds.push_to_hub("…", private=True, split="train")Private dataset, named split.
ds.push_to_hub("…", commit_message="add v2")Custom commit message in the dataset repo.

Arrow · mmapCache & memory

~/.cache/huggingface/datasets/Default cache dir. Set HF_DATASETS_CACHE to override.
HF_DATASETS_OFFLINE=1Force offline. Fail loud if a download is needed.
load_dataset(…, cache_dir="/data/hf")Per-call cache override.
ds.cleanup_cache_files()Delete intermediate map() caches.
ds.map(fn, load_from_cache_file=False)Force re-compute even when the cache is fresh.
ds.map(fn, cache_file_name="cached.arrow")Pin where the cache lands. Useful for reproducible pipelines.
ds.size_in_bytes, ds.cache_filesHow big is this dataset on disk?

Build · clean · push · ~35 linesEnd-to-end · CSV → Hub

Load two heterogeneous sources, give them an explicit schema, dedupe, stratify-split into train/val/test, save locally and push to the Hub.

python
from datasets import load_dataset, DatasetDict, Features, ClassLabel, Value

# 1 · Load a CSV from disk and a JSONL from a URL — same call shape
local = load_dataset("csv", data_files="reviews.csv", split="train")
remote = load_dataset(
    "json",
    data_files="https://example.com/reviews.jsonl",
    split="train",
)

# 2 · Concatenate and define an explicit schema
from datasets import concatenate_datasets
ds = concatenate_datasets([local, remote])

ds = ds.cast(Features({
    "text":  Value("string"),
    "label": ClassLabel(names=["neg", "pos"]),
}))

# 3 · Clean, dedupe, split
ds = ds.filter(lambda x: x["text"] and x["text"].strip())
ds = ds.shuffle(seed=42)

# train / val / test = 80 / 10 / 10
train_test = ds.train_test_split(test_size=0.2, seed=42, stratify_by_column="label")
val_test = train_test["test"].train_test_split(test_size=0.5, seed=42)

final = DatasetDict({
    "train": train_test["train"],
    "validation": val_test["train"],
    "test": val_test["test"],
})

# 4 · Save locally + push to the Hub
final.save_to_disk("./reviews_dataset")
final.push_to_hub("my-org/reviews", private=True)

Best practiceGood to know

Always pass batched=True to map() for tokenization. A vectorized tokenizer call on 1000 rows is dramatically faster than 1000 individual calls. The function just receives a dict-of-lists instead of a dict.
Use slice syntax at load time, not after. split="train[:1%]" only downloads what you need; load_dataset(…)[:1%] downloads the full split first.
Streaming for terabyte-scale corpora; cached Dataset for everything else. Streaming avoids disk pressure but loses random access and reproducibility. Most fine-tuning workflows want a cached Dataset.

Common trapsWatch out for

Streaming + .shuffle is approximate. The buffer is a sliding window — rows far apart in the file never meet. For true random order, materialize first.
map() with num_proc > 1 requires picklable functions. Closures over local state, tokenizers loaded outside the worker, and lambdas can all break multiprocessing silently. Define helpers at module scope.
Cache files survive across runs and silently feed stale results. Change your transform and forget to bust the cache → you’re training on yesterday’s data. Pass load_from_cache_file=False when iterating.

Go deeperSee also

HuggingFace Datasets FAQ

What is the HuggingFace Datasets library used for?

The HuggingFace Datasets library provides a fast, memory-efficient way to load, process, and share datasets for machine learning. It uses Apache Arrow for zero-copy memory mapping, so you can process datasets larger than RAM without running out of memory.

How does load_dataset work?

load_dataset('dataset_name') downloads a dataset from the HuggingFace Hub and caches it locally as Arrow files. You can pass a split ('train', 'test', 'validation'), a data_files path, or a streaming=True flag. Local CSV, JSON, and Parquet files are also supported.

What is the difference between Dataset and IterableDataset?

Dataset is fully loaded into memory-mapped Arrow files and supports random access and fast slicing. IterableDataset (streaming mode) yields examples lazily without downloading the whole dataset, which is essential for very large datasets that do not fit on disk.

How do I push a dataset to the HuggingFace Hub?

Call ds.push_to_hub('your-org/dataset-name') after logging in with huggingface-cli login. You can push individual splits, set private=True, or pass a commit_message. The Hub stores the dataset as Parquet shards so others can stream it without a full download.

Does HuggingFace Datasets work with PyTorch and TensorFlow?

Yes. Call ds.with_format('torch') or ds.with_format('tensorflow') to get framework-native tensors. For PyTorch, with_format returns a dataset compatible with DataLoader. For TensorFlow, use to_tf_dataset() to get a tf.data.Dataset with configurable batch size and shuffle.