2025, Nov 01 06:46
Экспорт из Polars в Excel: как убрать лишние нули и разделители тысяч
Почему Excel меняет вид чисел при экспорте из Polars и как это исправить: float_precision, dtype_formats, контроль округления и отключение разделителя тысяч.
Экспорт числовых данных из Polars в Excel кажется простым — пока в дело не вмешается форматирование. Типичная ситуация: значения Float64, округлённые в Python до двух знаков, в Excel внезапно получают лишний ноль на конце, а столбцы Int64 или Float64, где не было разделителей тысяч, начинают отображаться с ними. Сами значения корректны; расходится лишь то, как Excel их отображает.
Воспроизводимый пример
Ниже — конвейер, который читает Excel-файл со смешанными типами, считает сумму по группам, округляет все столбцы Float64 до двух знаков после запятой, помечает несоответствия и записывает результат обратно в .xlsx. Логика верная, но на выходном листе можно увидеть лишний ноль в конце и появившиеся разделители тысяч.
import polars as pl
import polars.selectors as sx
sheet = pl.read_excel('../Documents/abc.xlsx', engine='openpyxl')
sheet = sheet.with_columns(
sum_per_group=pl.col('Amount').sum().over('ID').sort_by('ID')
)
sheet = sheet.with_columns(
sx.by_dtype(pl.Float64).round(2)
)
sheet = sheet.with_columns([
pl.when(pl.col('sum_per_group') != pl.col('Total Amount'))
.then(pl.lit('No'))
.otherwise(pl.lit('Yes'))
.alias('Flag')
])
sheet.write_excel('abc_v2.xlsx')
Что на самом деле не так
Проблем две. Во‑первых, содержимое ячейки и его отображение — разные вещи. Polars записывает числа; а Excel, исходя из форматов чисел, решает, как их показывать. Если формат ячейки явно не задан, Excel выбирает свой вариант, который может не совпасть с вашими ожиданиями. Отсюда и лишний ноль на конце, и неожиданный разделитель тысяч.
Во‑вторых, настройки по умолчанию в Excel не совпадают с тем, что вы видите в консоли Python. Excel не ставит разделитель тысяч автоматически по мере ввода числа, а число отображаемых знаков после запятой часто зависит от ширины столбца и выбранного формата ячейки. Если на листе появляется разделитель тысяч или дополнительный ноль, это вопрос форматирования, а не изменения самих значений.
Ещё одна тонкость — различие между числами и текстом. Если на каком‑то этапе конвейера Excel получает текст вместо числа, управлять отображением через числовые форматы он уже не сможет. Если после шага округления вы замечаете появление разделителя тысяч, воспринимайте это как сигнал проверить, что на выходе остаются именно числовые значения, а не текст.
Практические решения, которые работают сейчас
Чтобы избавиться от лишнего нуля, управляйте точностью прямо при записи книги. Простой способ — указать float_precision при экспорте. Это удержит столбцы Float64 на двух знаках после запятой без неожиданных цифр.
# Оставьте тот же конвейер, затем экспортируйте с заданной точностью
sheet.write_excel('abc_v2.xlsx', float_precision=2)
Для разделителя тысяч самый надёжный на сегодня подход — не использовать Excel‑писатель Polars, если вам важно точное оформление на листе. Вместо этого применяйте pandas.to_excel или экспортируйте из Polars в CSV. Согласно текущим рекомендациям, стандартный движок xlsxwriter, используемый polars.write_excel, пока не достаточно зрел, поэтому, если нужен предсказуемый числовой вид без разделителей, практичнее выбрать pandas.to_excel или polars.write_csv.
# Альтернативный путь, когда требуется предсказуемое отображение в Excel
# 1) Запишите CSV напрямую из Polars
sheet.write_csv('abc_v2.csv')
Если остаётесь на экспорте в Excel через Polars, управляйте форматированием через соответствующие параметры. В частности, обратите внимание на float_precision и dtype_formats в polars.DataFrame.write_excel. Это отображение позволяет задать формат числа Excel для каждого dtype — он контролирует и число десятичных знаков, и разделители. Конкретный пример для управления внешним видом чисел — сопоставить Int64 и Float64 с явной строкой числового формата Excel.
# Пример управления форматами Excel по типам данных
# Подберите строку формата под желаемый вид чисел
# и исключает разделители тысяч.
sheet.write_excel(
'abc_v2.xlsx',
float_precision=2,
dtype_formats={
pl.Int64: '0',
pl.Float64: '0'
}
)
Так числовое останется числовым, а Excel будет отображать его по заданному вами формату, а не по настройкам листа по умолчанию. Если нужны две видимые десятичные, задайте соответствующий формат для Float64, чтобы отразить именно требуемый вид, и продолжайте использовать float_precision, чтобы исключить лишние цифры.
Почему это важно
Оценка конвейера данных часто происходит на «последней миле» — в таблице, которую открывает заинтересованная сторона. Если представление чисел расходится с тем, что вы видели в Python, возрастает риск неверного толкования, лишних проверок и переделок. Явно разделяйте сырые значения и правила отображения: заданное форматирование делает экспорт предсказуемым и повторяемым в разных средах.
Выводы
Относитесь к отображению в Excel как к задаче форматирования и задавайте его явно при экспорте. Используйте float_precision в Polars для контроля хвостовых разрядов. Когда на листе нельзя допускать разделители тысяч или требуется строгий стандарт отображения, опирайтесь на числовые форматы через dtype_formats или, если сейчас важнее простота, отдайте предпочтение pandas.to_excel либо переключитесь на CSV через polars.write_csv. Убедитесь, что конвейер сохраняет числовые типы до самой записи в файл, особенно на шагах, где числа могут непреднамеренно превратиться в текст. Такие осознанные настройки уберегут от неожиданных сюрпризов в файле, который пользователи действительно открывают.