Datasets 文档

加载 PDF 数据

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

加载 PDF 数据

PDF 支持目前处于实验阶段,可能会发生变化。

PDF 数据集具有 Pdf 类型的列,其中包含 pdfplumber 对象。

要处理 PDF 数据集,您需要安装 pdfplumber 包。请查看安装指南了解如何安装。

当您加载 PDF 数据集并调用 PDF 列时,PDF 将被解码为 pdfplumber 的 PDF 对象。

>>> from datasets import load_dataset, Pdf

>>> dataset = load_dataset("path/to/pdf/folder", split="train")
>>> dataset[0]["pdf"]
<pdfplumber.pdf.PDF at 0x1075bc320>

请先使用行索引,然后再使用 pdf 列来索引 PDF 数据集(例如 dataset[0]["pdf"]),以避免在数据集中创建所有的 PDF 对象。否则,如果您拥有大型数据集,这个过程可能会非常缓慢且耗时。

有关如何加载任何类型数据集的指南,请参阅通用加载指南

读取页面

使用 .pages 属性直接从 PDF 中访问页面。

然后您可以使用 pdfplumber 的函数来读取文本、表格和图像,例如:

>>> pdf = dataset[0]["pdf"]
>>> first_page = pdf.pages[0]
>>> first_page
<Page:1>
>>> first_page.extract_text()
Docling Technical Report
Version1.0
ChristophAuer MaksymLysak AhmedNassar MicheleDolfi NikolaosLivathinos
PanosVagenas CesarBerrospiRamis MatteoOmenetti FabianLindlbauer
KasperDinkla LokeshMishra YusikKim ShubhamGupta RafaelTeixeiradeLima
ValeryWeber LucasMorin IngmarMeijer ViktorKuropiatnyk PeterW.J.Staar
AI4KGroup,IBMResearch
Ru¨schlikon,Switzerland
Abstract
This technical report introduces Docling, an easy to use, self-contained, MIT-
licensed open-source package for PDF document conversion.
...
>>> first_page.images
In [24]: first_page.images
Out[24]: 
[{'x0': 256.5,
  'y0': 621.0,
  'x1': 355.49519999999995,
  'y1': 719.9952,
  'width': 98.99519999999995,
  'height': 98.99519999999995,
  'name': 'Im1',
  'stream': <PDFStream(44): raw=88980, {'Type': /'XObject', 'Subtype': /'Image', 'BitsPerComponent': 8, 'ColorSpace': /'DeviceRGB', 'Filter': /'DCTDecode', 'Height': 1024, 'Length': 88980, 'Width': 1024}>,
  'srcsize': (1024, 1024),
  'imagemask': None,
  'bits': 8,
  'colorspace': [/'DeviceRGB'],
  'mcid': None,
  'tag': None,
  'object_type': 'image',
  'page_number': 1,
  'top': 72.00480000000005,
  'bottom': 171.0,
  'doctop': 72.00480000000005}]
>>> first_page.extract_tables()
[]

您还可以将每个页面加载为 PIL.Image

>>> import PIL.Image
>>> import io
>>> first_page.to_image()
<pdfplumber.display.PageImage at 0x107d68dd0>
>>> buffer = io.BytesIO()
>>> first_page.to_image().save(buffer)
>>> img = PIL.Image.open(buffer)
>>> img
<PIL.PngImagePlugin.PngImageFile image mode=P size=612x792>

请注意,您可以向 .to_image() 传递 resolution= 参数,以渲染比默认值(72 ppi)更高分辨率的图像。

本地文件

您可以从 PDF 路径加载数据集。使用 cast_column() 函数来接收 PDF 文件路径列,并使用 Pdf 特性将其解码为 pdfplumber PDF 对象。

>>> from datasets import Dataset, Pdf

>>> dataset = Dataset.from_dict({"pdf": ["path/to/pdf_1", "path/to/pdf_2", ..., "path/to/pdf_n"]}).cast_column("pdf", Pdf())
>>> dataset[0]["pdf"]
<pdfplumber.pdf.PDF at 0x1657d0280>

如果您只想加载 PDF 数据集的底层路径而不想解码 PDF 对象,请在 Pdf 特性中设置 decode=False

>>> dataset = dataset.cast_column("pdf", Pdf(decode=False))
>>> dataset[0]["pdf"]
{'bytes': None,
 'path': 'path/to/pdf/folder/pdf0.pdf'}

PdfFolder

您还可以使用 PdfFolder 数据集构建器加载数据集,这样就不需要编写自定义数据加载器。这使得 PdfFolder 非常适合为不同的视觉任务快速创建和加载包含数千个 PDF 的数据集。您的 PDF 数据集结构应如下所示:

folder/train/resume/0001.pdf
folder/train/resume/0002.pdf
folder/train/resume/0003.pdf

folder/train/invoice/0001.pdf
folder/train/invoice/0002.pdf
folder/train/invoice/0003.pdf

如果数据集遵循 PdfFolder 结构,则可以直接使用 load_dataset() 加载。

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")

对于本地数据集,这相当于在 load_dataset() 中手动传递 pdffolder 并在 data_dir 中指定目录。

>>> dataset = load_dataset("pdffolder", data_dir="/path/to/folder")

然后您可以将 PDF 访问为 pdfplumber.pdf.PDF 对象。

>>> dataset["train"][0]
{"pdf": <pdfplumber.pdf.PDF at 0x161715e50>, "label": 0}

>>> dataset["train"][-1]
{"pdf": <pdfplumber.pdf.PDF at 0x16170bd90>, "label": 1}

要忽略元数据文件中的信息,请在 load_dataset() 中设置 drop_metadata=True

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)

如果您没有元数据文件,PdfFolder 会自动从目录名称推断标签名称。如果您想丢弃自动创建的标签,请设置 drop_labels=True。在这种情况下,您的数据集将仅包含一个 PDF 列。

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)

最后,filters 参数允许你仅加载数据集的子集,该子集基于标签或元数据的条件。如果你使用的是 Parquet 格式的元数据,这一点尤其有用,因为这种格式支持快速过滤。还建议将此参数与 streaming=True 一起使用,因为默认情况下,数据集会在过滤之前被完全下载。

>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)

有关创建您自己的 PdfFolder 数据集的更多信息,请参阅 创建 PDF 数据集 指南。

PDF 解码

默认情况下,当您迭代数据集时,PDF 将被顺序解码为 pdfplumber 的 PDF 对象。它会顺序解码 PDF 的元数据,直到您访问页面时才会读取 PDF 页面。

不过,通过使用多线程解码,可以显著提高数据集的处理速度。

>>> import os
>>> num_threads = num_threads = min(32, (os.cpu_count() or 1) + 4)
>>> dataset = dataset.decode(num_threads=num_threads)
>>> for example in dataset:  # up to 20 times faster !
...     ...

您可以使用 num_threads 启用多线程。这对于加快远程数据流传输特别有用。但是,对于快速磁盘上的本地数据,它可能比 num_threads=0 慢。

如果您不需要将文档解码为 pdfplumber PDF 对象,而希望直接访问路径或字节流,您可以禁用解码。

>>> dataset = dataset.decode(False)

注意:IterableDataset.decode() 目前仅适用于流式数据集。

在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.