Ошибка python read_fwf: 'dtype не поддерживается парсером python-fwf'

Используя python 2.7.5 и pandas 0.12.0, я пытаюсь импортировать текстовые файлы с фиксированной шириной шрифта в DataFrame с помощью "pd.io.parsers.read_fwf()". Значения, которые я импортирую, являются числовыми, но важно, чтобы начальные нули сохранялись, поэтому я хотел бы указать dtype как строку, а не int.

В соответствии с документацией для этой функции атрибут dtype поддерживается в read_fwf, но когда я пытаюсь его использовать:

data= pd.io.parsers.read_fwf(file, colspecs = ([79,81], [87,90]), header = None, dtype = {0: np.str, 1: np.str})

Я получаю сообщение об ошибке:

ValueError: dtype is not supported with python-fwf parser

Я пробовал столько вариаций, сколько могу придумать для установки 'dtype = something', но все они возвращают одно и то же сообщение.

Любая помощь будет очень признательна!

Ответ 1

Вместо указания dtypes укажите конвертер для столбца, который вы хотите сохранить как str, основываясь на примере @TomAugspurger:

from io import StringIO
import pandas as pd
data = StringIO(u"""
121301234
121300123
121300012
""")

pd.read_fwf(data, colspecs=[(0,3),(4,8)], converters = {1: str})

Приводит к

    \n Unnamed: 1
0  121       0123
1  121       0012
2  121       0001

Преобразователи - это отображение из имени столбца или индекса в функцию для преобразования значения в ячейку (например, int преобразует их в целое число, float в float и т.д.)

Ответ 2

Документация, вероятно, неверна. Я думаю, что одна и та же базовая docstring используется для нескольких читателей. Что касается обходного пути, так как вы знаете ширину раньше времени, я думаю, вы можете добавить нули после факта.

С этим файлом и шириной [4, 5]

121301234
121300123
121300012

получаем:

In [38]: df = pd.read_fwf('tst.fwf', widths=[4,5], header=None)

In [39]: df
Out[39]: 
      0     1
0  1213  1234
1  1213   123
2  1213    12

Чтобы заполнить недостающие нули, будет ли это работать?

In [45]: df[1] = df[1].astype('str')

In [53]: df[1] = df[1].apply(lambda x: ''.join(['0'] * (5 - len(x))) + x)

In [54]: df
Out[54]: 
      0      1
0  1213  01234
1  1213  00123
2  1213  00012

5 в лямбда выше происходит с правильной ширины. Вам нужно выбрать все столбцы, которым нужны ведущие нули, и применить функцию (с правильной шириной) к каждому.