Сообщить об ошибке.

Чтение файлов со столбцами фиксированной ширины в pandas

Функция pandas.read_fwf() модуля pandas в Python

Синтаксис:

import pandas

df = pandas.read_fwf(filepath_or_buffer, *, colspecs='infer', widths=None, 
                     infer_nrows=100, dtype_backend='numpy_nullable', 
                     iterator=False, chunksize=None, **kwds)

Параметры:

  • filepath_or_buffer - любой допустимый путь в виде строки. Строка может быть URL. Допустимые схемы URL включают http(s), ftp(s), s3, gs и file. Для URL-адресов файлов ожидается host. Локальным файлом может быть: file://localhost/path/to/table.csv.

    Если необходимо передать объект pathlib, то этот аргумент принимает любой оs.PathLike.

    Аргумент также поддерживает объекты подобные открытому файлу, у которых есть метод file.read(), такие как дескриптор файла (например, открытый файл open()) или io.StringIO.

  • colspecs='infer' - список пар (кортежей), задающий размеры полей фиксированной ширины каждой строки в виде полуоткрытых интервалов (т. е. [from, to[). Чтобы синтаксический анализатор pandas попытался сам определить характеристики столбца из первых 100 строк данных, можно указать строковое значение 'infer'. Поведение по умолчанию 'infer'.

  • widths=None - список ширин полей, который можно использовать вместо colspecs, если интервалы смежные.

  • infer_nrows=100 - количество строк, которое следует учитывать при автоматическом определять colspecs.

  • iterator=False - возвращает объект TextFileReader для итерации или получения фрагментов с помощью get_chunk().

  • chunksize=None - количество строк для чтения фрагмента из файла. Передача значения приведет к тому, что функция вернет объект TextFileReader для итерации.

  • **kwds - необязательные ключевые аргументы, которые передаются в TextFileReader (принимает delimiter).

  • dtype_backend='numpy_nullable' - (экспериментальный) внутренний тип данных, применяемый к результирующему DataFrame.

    Поведение выглядит следующим образом:

    • 'numpy_nullable': возвращает фрейм с поддержкой null-dtype (по умолчанию).
    • 'pyarrow': возвращает фрейм данных ArrowDtype с нулевым значением, поддерживаемый pyarrow.

Возвращаемое значение:

Описание pandas.read_fwf():

Функция pandas.read_fwf() модуля pandas читает таблицу форматированных строк фиксированной ширины в DataFrame. Также поддерживает опциональную итерацию или разбиение файла на куски.

Функция pandas.read_fwf() работает с файлами данных, которые имеют известную и фиксированную ширину столбцов. Параметры функции pandas.read_fwf() во многом такие же, как и pandas.read_csv(), с двумя дополнительными аргументами и другим использованием разделителя delimiter:

  • Аргумент colspecs: список пар (кортежей), задающий размеры полей фиксированной ширины каждой строки в виде полуоткрытых интервалов (т. е. [from, to[). Чтобы синтаксический анализатор pandas попытался сам определить характеристики столбца из первых 100 строк данных, можно указать строковое значение 'infer'. Поведение по умолчанию 'infer'.
  • Аргумент widths: список ширин полей, который можно использовать вместо colspecs, если интервалы смежные.
  • Аргумент delimiter (принимает TextFileReader()): символы, которые следует рассматривать как символы-заполнители в файле со столбцами фиксированной ширины. Может использоваться для указания символа-заполнителя полей, если это не пробелы (например, '~').

Рассмотрим типичный файл данных с ячейками фиксированной ширины:

data1 = (
    "id8141    360.242940   149.910199   11950.7\n"
    "id1594    444.953632   166.985655   11788.4\n"
    "id1849    364.136849   183.628767   11806.2\n"
    "id1230    413.836124   184.375703   11916.8\n"
    "id1948    502.953953   173.237159   12468.3"
)

# запишем данные в файл
with open("bar.csv", "w") as f:
    f.write(data1)

Чтобы проанализировать этот файл в DataFrame, необходимо просто передать спецификации столбца в функцию read_fwf() вместе с именем файла:

# аргумент `colspecs` представляет собой список полуинтервалов
>>> colspecs = [(0, 6), (8, 20), (21, 33), (34, 43)]
>>> df = pd.read_fwf("bar.csv", colspecs=colspecs, header=None, index_col=0)
>>> df
#                  1           2        3
# 0                                      
# id8141  360.242940  149.910199  11950.7
# id1594  444.953632  166.985655  11788.4
# id1849  364.136849  183.628767  11806.2
# id1230  413.836124  184.375703  11916.8
# id1948  502.953953  173.237159  12468.3

Обратите внимание, как анализатор автоматически выбирает имена столбцов X.<column number>, когда указан аргумент header = None. В качестве альтернативы, можно указать только ширину для смежных столбцов:

# аргумент `widths` представляет собой список целых чисел.
>>> widths = [6, 14, 13, 10]
>>> df = pd.read_fwf("bar.csv", widths=widths, header=None)
>>> df
#         0           1           2        3
# 0  id8141  360.242940  149.910199  11950.7
# 1  id1594  444.953632  166.985655  11788.4
# 2  id1849  364.136849  183.628767  11806.2
# 3  id1230  413.836124  184.375703  11916.8
# 4  id1948  502.953953  173.237159  12468.3

Анализатор учтет дополнительные пробелы вокруг столбцов, поэтому в файле можно использовать дополнительное разделение между столбцами.

По умолчанию pandas.read_fwf() попытается определить colspecs файла, используя первые 100 строк. Pandas делает это только в тех случаях, когда столбцы выровнены и правильно разделены разделителем delimiter (разделителем по умолчанию является пробел).

>>> df = pd.read_fwf("bar.csv", header=None, index_col=0)
>>> df
#                  1           2        3
# 0                                      
# id8141  360.242940  149.910199  11950.7
# id1594  444.953632  166.985655  11788.4
# id1849  364.136849  183.628767  11806.2
# id1230  413.836124  184.375703  11916.8
# id1948  502.953953  173.237159  12468.3

Функция read_fwf() поддерживает аргумент dtype для указания типов анализируемых столбцов, которые должны отличаться от предполагаемого типа.

>>> pd.read_fwf("bar.csv", header=None, index_col=0).dtypes
# 1    float64
# 2    float64
# 3    float64
# dtype: object

>>> pd.read_fwf("bar.csv", header=None, dtype={2: "object"}).dtypes
# 0     object
# 1    float64
# 2     object
# 3    float64
# dtype: object