# Загрузка данных PDF

> [!WARNING]
> Поддержка PDF является экспериментальной и может быть изменена.

Наборы данных Pdf имеют столбцы типа [Pdf](/docs/datasets/v5.2.0/ru/package_reference/main_classes#datasets.Pdf), которые содержат объекты `pdfplumber`.

> [!TIP]
> Для работы с наборами данных в формате PDF необходимо установить пакет `pdfplumber`. Ознакомьтесь с руководством по [установке](https://github.com/jsvine/pdfplumber#installation), чтобы узнать, как это сделать.

При загрузке датасета pdf и обращении к столбцу pdf файлы pdf декодируются как Pdf из `pdfplumber`:

```py
>>> from datasets import load_dataset, Pdf

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

> [!WARNING]
> Обращайтесь к набору данных PDF сначала по индексу строки, а затем по столбцу `pdf` — `dataset[0]["pdf"]` — чтобы избежать создания всех объектов PDF в наборе данных. В противном случае при работе с большим набором данных этот процесс может оказаться медленным и требующим много времени.

Справочник по загрузке любого типа набора данных см. в общем руководстве по загрузке.

## Читать страницы

Обращайтесь к страницам напрямую из PDF с помощью атрибута `.pages`.

Затем вы можете использовать функции `pdfplumber` для чтения текстов, таблиц и изображений, например:

```python
>>> 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`:

```python
>>> 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>
```

Обратите внимание, что вы можете передать `resolution=` в `.to_image()`, чтобы отобразить изображение с более высоким разрешением, чем значение по умолчанию (72 ppi).

## Локальные файлы

Вы можете загрузить набор данных по пути к файлу PDF. Используйте функцию [cast_column()](/docs/datasets/v5.2.0/ru/package_reference/main_classes#datasets.Dataset.cast_column), чтобы принять столбец с путями к файлам PDF и декодировать его в PDF с помощью `pdfplumber` с фичей [Pdf](/docs/datasets/v5.2.0/ru/package_reference/main_classes#datasets.Pdf):
```py
>>> 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, установите `decode=False` в фиче [Pdf](/docs/datasets/v5.2.0/ru/package_reference/main_classes#datasets.Pdf):

```py
>>> 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()](/docs/datasets/v5.2.0/ru/package_reference/loading_methods#datasets.load_dataset):

```py
>>> from datasets import load_dataset

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

Для локальных наборов данных это эквивалентно ручной передаче `pdffolder` в [load_dataset()](/docs/datasets/v5.2.0/ru/package_reference/loading_methods#datasets.load_dataset) и указанию каталога в `data_dir`:

```py
>>> 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}
```

Чтобы игнорировать информацию в файле метаданных, установите `drop_metadata=True` в [load_dataset()](/docs/datasets/v5.2.0/ru/package_reference/loading_methods#datasets.load_dataset):

```py
>>> from datasets import load_dataset

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

Если у вас нет файла метаданных, `PdfFolder` автоматически выводит имя метки из имени каталога. Если вы хотите отбросить автоматически созданные метки, установите `drop_labels=True`. В этом случае ваш набор данных будет содержать только столбец pdf:

```py
>>> from datasets import load_dataset

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

Наконец, аргумент `filters` позволяет загрузить только часть набора данных на основе условия, наложенного на метку или метаданные. Это особенно полезно, если метаданные хранятся в формате Parquet, поскольку этот формат обеспечивает быструю фильтрацию. Также рекомендуется использовать этот аргумент вместе с `streaming=True`, так как по умолчанию набор данных полностью загружается до применения фильтрации.

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

> [!TIP]
> Для получения дополнительной информации о создании собственного набора данных `PdfFolder` ознакомьтесь с руководством [Create a pdf dataset](./document_dataset).

## Декодирование PDF

По умолчанию PDF-файлы декодируются последовательно как `PDFs` pdfplumber при итерации по набору данных. Метаданные PDF-файлов декодируются последовательно, а сами страницы PDF не читаются, пока вы к ним не обратитесь.

Однако с помощью многопоточного декодирования можно значительно ускорить работу с набором данных:

```python
>>> 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`.

Если вас не интересуют документы, декодированные как `PDFs` с помощью pdfplumber, и вы хотите получить доступ к пути/байтам, вы можете отключить декодирование:

```python
>>> dataset = dataset.decode(False)
```

Примечание: [IterableDataset.decode()](/docs/datasets/v5.2.0/ru/package_reference/main_classes#datasets.IterableDataset.decode) в настоящее время доступен только для потоковых наборов данных.

