Datasets 文档
加载
并获得增强的文档体验
开始使用
加载
您的数据可以存储在不同的地方;它们可以位于本地机器的磁盘上、Github 仓库中,或者内存数据结构(如 Python 字典和 Pandas DataFrame)中。无论数据集存储在哪里,🤗 Datasets 都能帮助您将其加载。
本指南将向您展示如何从以下位置加载数据集:
- Hugging Face Hub
- 本地文件
- 内存数据
- 离线状态
- 拆分后的特定切片
有关加载其他数据集模态的详细信息,请查看音频数据集加载指南、图像数据集加载指南、视频数据集加载指南或文本数据集加载指南。
Hugging Face Hub
您还可以从 Hub 上的任何数据集仓库加载数据集!首先创建一个数据集仓库并上传您的数据文件。现在您可以使用 load_dataset() 函数来加载该数据集。
例如,尝试通过提供仓库命名空间和数据集名称,从这个演示仓库加载文件。该数据集仓库包含 CSV 文件,下面的代码演示了如何从 CSV 文件中加载数据集
>>> from datasets import load_dataset
>>> dataset = load_dataset("lhoestq/demo1")某些数据集可能基于 Git 标签、分支或提交拥有多个版本。请使用 revision 参数来指定您想要加载的数据集版本
>>> dataset = load_dataset(
... "lhoestq/custom_squad",
... revision="main" # tag name, or branch name, or commit hash
... )有关如何在 Hub 上创建数据集仓库以及如何上传数据文件的更多详细信息,请参阅将数据集上传到 Hub 教程。
默认情况下,数据集会将所有数据加载到 train 拆分中,或者检查数据文件名中是否包含拆分名称(例如“train”、“test”和“validation”)。使用 data_files 参数将数据文件映射到诸如 train、validation 和 test 等拆分中
>>> data_files = {"train": "train.csv", "test": "test.csv"}
>>> dataset = load_dataset("namespace/your_dataset_name", data_files=data_files)如果您没有指定要使用哪些数据文件,load_dataset() 将返回所有数据文件。如果您加载像 C4 这样的大型数据集(约 13TB 数据),这可能需要很长时间。
您还可以使用 data_files 或 data_dir 参数加载文件的特定子集。这些参数可以接受一个相对路径,该路径会解析为加载数据集时的基准路径。
>>> from datasets import load_dataset
# load files that match the grep pattern
>>> c4_subset = load_dataset("allenai/c4", data_files="en/c4-train.0000*-of-01024.json.gz")
# load dataset from the en directory on the Hub
>>> c4_subset = load_dataset("allenai/c4", data_dir="en")split 参数也可以将数据文件映射到特定的拆分
>>> data_files = {"validation": "en/c4-validation.*.json.gz"}
>>> c4_validation = load_dataset("allenai/c4", data_files=data_files, split="validation")本地和远程文件
数据集可以从存储在您计算机上的本地文件以及远程文件加载。数据集最常存储为 csv、json、txt 或 parquet 文件。load_dataset() 函数可以加载上述每种文件类型。
CSV
🤗 Datasets 可以读取由一个或多个 CSV 文件组成的数据集(在这种情况下,请将您的 CSV 文件作为列表传递)
>>> from datasets import load_dataset
>>> dataset = load_dataset("csv", data_files="my_file.csv")有关详细信息,请查看如何从 CSV 文件加载表格数据集指南。
JSON
JSON 文件可以直接使用 load_dataset() 加载,如下所示
>>> from datasets import load_dataset
>>> dataset = load_dataset("json", data_files="my_file.json")JSON 文件格式多种多样,但我们认为最高效的格式是拥有多个 JSON 对象;每一行代表一个独立的数据行。例如
{"a": 1, "b": 2.0, "c": "foo", "d": false}
{"a": 4, "b": -5.5, "c": null, "d": true}您可能遇到的另一种 JSON 格式是嵌套字段,在这种情况下,您需要指定 field 参数,如下所示
{"version": "0.1.0",
"data": [{"a": 1, "b": 2.0, "c": "foo", "d": false},
{"a": 4, "b": -5.5, "c": null, "d": true}]
}
>>> from datasets import load_dataset
>>> dataset = load_dataset("json", data_files="my_file.json", field="data")要通过 HTTP 加载远程 JSON 文件,请直接传入 URL
>>> base_url = "https://rajpurkar.github.io/SQuAD-explorer/dataset/"
>>> dataset = load_dataset("json", data_files={"train": base_url + "train-v1.1.json", "validation": base_url + "dev-v1.1.json"}, field="data")虽然这些是最常见的 JSON 格式,但您会看到其他格式不同的数据集。🤗 Datasets 能够识别这些其他格式,并相应地回退到 Python 的 JSON 加载方法来处理它们。
Parquet
Parquet 文件采用列式存储格式,这与 CSV 等基于行的文件不同。大型数据集可能会存储在 Parquet 文件中,因为它在返回查询结果时更高效且速度更快。
加载 Parquet 文件
>>> from datasets import load_dataset
>>> dataset = load_dataset("parquet", data_files={'train': 'train.parquet', 'test': 'test.parquet'})要通过 HTTP 加载远程 Parquet 文件,请直接传入 URL
>>> base_url = "https://huggingface.co/datasets/wikimedia/wikipedia/resolve/main/20231101.ab/"
>>> data_files = {"train": base_url + "train-00000-of-00001.parquet"}
>>> wiki = load_dataset("parquet", data_files=data_files, split="train")Arrow
Arrow 文件采用内存列式格式存储,这与 CSV 等基于行的格式以及 Parquet 等未压缩格式不同。
加载 Arrow 文件
>>> from datasets import load_dataset
>>> dataset = load_dataset("arrow", data_files={'train': 'train.arrow', 'test': 'test.arrow'})要通过 HTTP 加载远程 Arrow 文件,请直接传入 URL
>>> base_url = "https://huggingface.co/datasets/croissantllm/croissant_dataset/resolve/main/english_660B_11/"
>>> data_files = {"train": base_url + "train/data-00000-of-00080.arrow"}
>>> wiki = load_dataset("arrow", data_files=data_files, split="train")Arrow 是 🤗 Datasets 底层使用的文件格式,因此您可以直接使用 Dataset.from_file() 加载本地 Arrow 文件
>>> from datasets import Dataset
>>> dataset = Dataset.from_file("data.arrow")与 load_dataset() 不同,Dataset.from_file() 会对 Arrow 文件进行内存映射,而不会在缓存中准备数据集,从而为您节省磁盘空间。在这种情况下,存储中间处理结果的缓存目录将是 Arrow 文件所在的目录。
目前仅支持 Arrow 流式格式。不支持 Arrow IPC 文件格式(也称为 Feather V2)。
Lance
Lance 是一种用于 AI 的开源多模态湖仓表格式。Lance 表不仅可以原生存储文本和标量值,还可以在您的表格数据旁边存储大型二进制对象(blobs),例如图像、音频和视频。
>>> from datasets import load_dataset
>>> lance_base_url = "lance-format/laion-1m"要流式传输数据集而不将其复制到您的本地机器,请指定 streaming=True 参数
ds = load_dataset(lance_base_url, split="train", streaming=True)
# Take first three rows
for row in ds.take(3):
print(row["caption"], row["image"])这将会在单次请求中返回图像标题和图像字节。
HDF5 文件
HDF5 文件常用于在科学计算和机器学习中存储大量数值数据。使用 🤗 Datasets 加载 HDF5 文件与加载 CSV 文件类似
>>> from datasets import load_dataset
>>> dataset = load_dataset("hdf5", data_files="data.h5")请注意,HDF5 加载器假定文件具有“表格”结构,即文件中的所有数据集在第一维度上具有(相同数量的)行。
SQL
通过指定连接到数据库的 URI,使用 from_sql() 读取数据库内容。您可以读取表名和查询结果
>>> from datasets import Dataset
# load entire table
>>> dataset = Dataset.from_sql("data_table_name", con="sqlite:///sqlite_file.db")
# load from query
>>> dataset = Dataset.from_sql("SELECT text FROM table WHERE length(text) > 100 LIMIT 10", con="sqlite:///sqlite_file.db")有关详细信息,请查看如何从 SQL 数据库加载表格数据集指南。
WebDataset
WebDataset 格式基于 TAR 归档,适用于大型图像数据集。由于其规模巨大,WebDataset 通常以流式模式加载(使用 streaming=True)。
您可以像这样加载 WebDataset:
>>> from datasets import load_dataset
>>>
>>> path = "path/to/train/*.tar"
>>> dataset = load_dataset("webdataset", data_files={"train": path}, split="train", streaming=True)要通过 HTTP 加载远程 WebDataset,请直接传入 URL
>>> from datasets import load_dataset
>>>
>>> base_url = "https://huggingface.co/datasets/lhoestq/small-publaynet-wds/resolve/main/publaynet-train-{i:06d}.tar"
>>> urls = [base_url.format(i=i) for i in range(4)]
>>> dataset = load_dataset("webdataset", data_files={"train": urls}, split="train", streaming=True)远程文件
如果您有存储为 csv、json、txt、parquet 或任何受支持格式的远程文件,load_dataset() 函数可以通过指定远程路径来加载它们
- 用于公共在线文件的
https://URL,例如data_files=["https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json"] - 用于 Hugging Face 上任何数据集仓库或存储桶中文件的
hf://URL,例如data_files=["hf://datasets/karpathy/tinystories-gpt4-clean/tinystories_gpt4_clean.parquet"]或data_files=["hf://buckets/julien-c/my-training-bucket/julien/affluence.csv"]
多进程处理
当数据集由多个文件(我们称之为“分片/shards”)组成时,可以显著加快数据集下载和准备步骤。
您可以使用 num_proc 选择并行准备数据集所需的进程数量。在这种情况下,每个进程都会分配一部分分片进行准备
from datasets import load_dataset
imagenet = load_dataset("timm/imagenet-1k-wds", num_proc=8)
ml_librispeech_spanish = load_dataset("facebook/multilingual_librispeech", "spanish", num_proc=8)内存数据
🤗 Datasets 还允许您直接从内存数据结构(如 Python 字典和 Pandas DataFrame)创建 Dataset。
Python 字典
使用 from_dict() 加载 Python 字典
>>> from datasets import Dataset
>>> my_dict = {"a": [1, 2, 3]}
>>> dataset = Dataset.from_dict(my_dict)Python 字典列表
使用 from_list() 加载 Python 字典列表
>>> from datasets import Dataset
>>> my_list = [{"a": 1}, {"a": 2}, {"a": 3}]
>>> dataset = Dataset.from_list(my_list)Python 生成器
使用 from_generator() 从 Python 生成器创建数据集
>>> from datasets import Dataset
>>> def my_gen():
... for i in range(1, 4):
... yield {"a": i}
...
>>> dataset = Dataset.from_generator(my_gen)这种方法支持加载超过可用内存大小的数据。
您还可以通过向 gen_kwargs 传递列表来定义分片数据集
>>> def gen(shards):
... for shard in shards:
... with open(shard) as f:
... for line in f:
... yield {"line": line}
...
>>> shards = [f"data{i}.txt" for i in range(32)]
>>> ds = IterableDataset.from_generator(gen, gen_kwargs={"shards": shards})
>>> ds = ds.shuffle(seed=42, buffer_size=10_000) # shuffles the shards order + uses a shuffle buffer
>>> from torch.utils.data import DataLoader
>>> dataloader = DataLoader(ds.with_format("torch"), num_workers=4) # give each worker a subset of 32/4=8 shardsPandas DataFrame
使用 from_pandas() 加载 Pandas DataFrame
>>> from datasets import Dataset
>>> import pandas as pd
>>> df = pd.DataFrame({"a": [1, 2, 3]})
>>> dataset = Dataset.from_pandas(df)有关详细信息,请查看如何从 Pandas DataFrame 加载表格数据集指南。
离线状态
即使您没有互联网连接,仍然可以加载数据集。只要您之前从 Hub 仓库下载过该数据集,它就应该已被缓存。这意味着您可以从缓存中重新加载数据集并离线使用。
如果您知道自己无法联网,可以在完全离线模式下运行 🤗 Datasets。这可以节省时间,因为 🤗 Datasets 会直接查看缓存,而不是等待数据集构建器下载超时。将环境变量 HF_HUB_OFFLINE 设置为 1 以启用完全离线模式。
切分拆分
您还可以选择仅加载拆分的特定切片。有两种切分方式:使用字符串或使用 ReadInstruction API。对于简单情况,字符串更简洁且易于阅读;而当使用可变切分参数时,ReadInstruction 更易于使用。
连接 train 和 test 拆分:
>>> train_test_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train+test")选择 train 拆分的特定行
>>> train_10_20_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[10:20]")或使用以下方式选择拆分的百分比
>>> train_10pct_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[:10%]")从每个拆分中选择百分比组合
>>> train_10_80pct_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[:10%]+train[-80%:]")最后,您甚至可以创建交叉验证拆分。下面的示例创建了 10 折交叉验证拆分。每个验证数据集是一个 10% 的数据块,而训练数据集构成了剩余互补的 90% 数据块
>>> val_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split=[f"train[{k}%:{k+10}%]" for k in range(0, 100, 10)])
>>> train_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split=[f"train[:{k}%]+train[{k+10}%:]" for k in range(0, 100, 10)])百分比切分与舍入
默认行为是将边界舍入到最接近的整数,适用于请求的切分边界无法被 100 整除的数据集。如下所示,某些切片可能包含的示例比其他切片多。例如,如果下面的训练拆分包含 999 条记录,那么
# 19 records, from 500 (included) to 519 (excluded).
>>> train_50_52_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[50%:52%]")
# 20 records, from 519 (included) to 539 (excluded).
>>> train_52_54_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[52%:54%]")如果您想要大小相等的拆分,请改用 pct1_dropremainder 舍入方式。这会将指定的百分比边界视为 1% 的倍数。
# 18 records, from 450 (included) to 468 (excluded).
>>> train_50_52pct1_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split=datasets.ReadInstruction("train", from_=50, to=52, unit="%", rounding="pct1_dropremainder"))
# 18 records, from 468 (included) to 486 (excluded).
>>> train_52_54pct1_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split=datasets.ReadInstruction("train",from_=52, to=54, unit="%", rounding="pct1_dropremainder"))
# Or equivalently:
>>> train_50_52pct1_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[50%:52%](pct1_dropremainder)")
>>> train_52_54pct1_ds = datasets.load_dataset("ajibawa-2023/General-Stories-Collection", split="train[52%:54%](pct1_dropremainder)")如果数据集中的示例数量不能被 100 整除,
pct1_dropremainder舍入方式可能会截断数据集中的最后几个示例。
疑难解答
有时,加载数据集时可能会得到意外的结果。您可能遇到的两个最常见问题是手动下载数据集和指定数据集的特征。
指定特征
当您从本地文件创建数据集时,Features 会由 Apache Arrow 自动推断。但是,数据集的特征可能并不总是符合您的预期,或者您可能希望自己定义特征。下面的示例展示了如何使用 ClassLabel 特征添加自定义标签。
首先使用 Features 类定义您自己的标签
>>> class_names = ["sadness", "joy", "love", "anger", "fear", "surprise"]
>>> emotion_features = Features({'text': Value('string'), 'label': ClassLabel(names=class_names)})接下来,在 load_dataset() 中通过 features 参数指定您刚刚创建的特征
>>> dataset = load_dataset('csv', data_files=file_dict, delimiter=';', column_names=['text', 'label'], features=emotion_features)现在查看您的数据集特征时,您可以看到它使用了您定义的自定义标签
>>> dataset['train'].features
{'text': Value('string'),
'label': ClassLabel(names=['sadness', 'joy', 'love', 'anger', 'fear', 'surprise'])}