2025, Nov 22 09:01

Надёжный импорт Excel в pandas при пустом последнем столбце

Как корректно читать Excel в pandas, если последний столбец пуст или без заголовка. Избегайте usecols, импортируйте всё и выбирайте нужное через iloc.

Разбор Excel‑файлов, которыми вы не управляете, становится непростым, если структура неоднородна. Обычный случай: несколько корректных столбцов с заголовками и замыкающий столбец без заголовка, который часто пустой. Попытка жёстко зафиксировать диапазон столбцов при импорте может привести к предупреждениям и тихо «отбросить» этот последний столбец, если вверху у него нет данных.

Как воспроизвести проблему

Представьте лист Excel, где столбцы A–D имеют заголовки и данные, а столбец E — без заголовка и может быть пустым в верхней части или полностью пустым. Чтение фиксированного диапазона в pandas выглядит очевидным, но именно оно и вызывает проблемы:

import pandas as pd

xls_path = "input.xlsx"
chopped_df = pd.read_excel(xls_path, usecols="A:E")

Это может привести к предупреждению вида: FutureWarning: Defining usecols with out of bounds indices is deprecated and will raise a ParserError in a future version. Кроме того, пятый столбец не вернётся в случаях, когда он пуст вверху или целиком пуст. Передача явного списка индексов вроде usecols=[0, 1, 2, 3, 4] в этой ситуации даёт те же предупреждение и поведение.

Почему так происходит

Если замыкающий столбец полностью пуст, pandas вообще не загружает его из Excel. Насильственное включение такого столбца в диапазон делает выборку выходящей за пределы фактически прочитанных данных — отсюда предупреждение и отсутствие столбца. Если указать pandas трактовать первую строку как данные (header=None), пустые ячейки в верхних строках будут заполнены NaN, но столбец, который целиком пуст, всё равно не будет считан из файла. В этом случае попытка протолкнуть его через usecols приведёт к той же ситуации выхода за границы. После импорта вы всегда можете посмотреть на DataFrame и добавить новый столбец в pandas, если вам нужна такая «заглушка».

Практическое решение

Вместо того чтобы ограничивать столбцы на этапе чтения, импортируйте лист как есть и выбирайте нужное из полученного DataFrame. Так вы избежите выходов за границы из‑за полностью пустых столбцов и сможете стабильно обращаться к последнему столбцу, когда в нём действительно есть данные.

import pandas as pd

file_uri = "test.xlsx"
full_df = pd.read_excel(file_uri)

# Выбираем последний столбец независимо от его имени и наличия/отсутствия заголовка
last_col_df = full_df.iloc[0:, -1:]
print(last_col_df)

Здесь iloc[0:, -1:] берёт все строки и только последний столбец. Если в замыкающем столбце есть значения хотя бы в одной строке, он будет присутствовать в DataFrame, и такая выборка сработает. Если столбец полностью пуст и потому не был прочитан, «последним» окажется просто последний столбец, в котором есть данные.

Почему это важно

Зависимость от жёстко заданного диапазона столбцов в Excel ломается, когда источник добавляет или убирает завершающие пустые столбцы, либо когда столбец временно пуст. Описанное поведение уже сегодня приводит к предупреждениям об устаревании и в будущих версиях pandas может перерасти в ParserError. Убрав зависимость от usecols для потенциально пустых столбцов, вы сделаете конвейер импорта устойчивее к реальным таблицам.

Выводы

Если работаете с необязательным или часто пустым последним столбцом, не фиксируйте Excel‑диапазон через usecols. Сначала прочитайте лист, затем выберите столбцы из полученного DataFrame. Если важно, чтобы пустые верхние ячейки сохранялись как NaN, читайте с header=None, чтобы верхняя строка осталась данными; просто помните, что полностью пустой столбец всё равно не будет загружен и, если он необходим, его придётся добавить позже в pandas. Такой небольшой сдвиг в подходе делает код устойчивее к будущим изменениям, убирает предупреждения и аккуратно справляется с «шероховатостями» неподконтрольных Excel‑входов.