Как прочитать текстовый файл с фиксированной шириной в пандах? - PullRequest
10 голосов
/ 15 марта 2012

Я только что взял в руки панд и выясняю, как я могу прочитать файл. Этот файл взят из базы данных WRDS и представляет собой список компонентов SP500 вплоть до 1960-х годов. Я проверил файл и что бы я ни делал, чтобы импортировать его с помощью read_csv, я все равно не могу правильно отобразить данные.

df = read_csv('sp500-sb.txt')

df

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1231 entries, 0 to 1230
Data columns: gvkeyx      from      thru     conm
                                        gvkey      co_conm
...(the column names)
dtypes: object(1)

Что означает вышеупомянутый блок вывода? Все будет полезно

Ответы [ 4 ]

10 голосов
/ 27 октября 2015

pandas.read_fwf() был добавлен в панды 0.7.3 ( апрель 2012 ) для обработки файлов фиксированной ширины.

  1. Справочник по API

  2. Пример из другого вопроса

8 голосов
/ 16 марта 2012

Уэс ответил мне по электронной почте. Приветствия.

Это файл с фиксированной шириной (не разделенный запятыми или табуляцией как обычный). Я понимаю, что у панд нет читателя с фиксированной шириной, как R делает, хотя можно сделать очень легко. Я посмотрю, что я могу делать. В то же время, если вы можете экспортировать данные в другом формате (например, csv - разделенный запятыми) вы сможете прочитать его с помощью read_csv. я Подозреваю, что с некоторой магией Unix вы можете преобразовать файл FWF в CSV файл.

Я рекомендую следить за проблемой на github, так как ваша электронная почта вот-вот исчезнуть из моего почтового ящика:)

https://github.com/pydata/pandas/issues/920

лучше, Wes

0 голосов
/ 17 марта 2012

пользователь, если вам нужно иметь дело с фиксированным форматом прямо сейчас, вы можете использовать что-то вроде следующего:

def fixed_width_to_items(filename, fields, first_column_is_index=False, ignore_first_rows=0):
    reader = open(filename, 'r')
    # skip first rows 
    for i in xrange(ignore_first_rows):
        reader.next()
    if first_column_is_index:
        index = slice(0, fields[1])
        fields = [slice(*x) for x  in zip(fields[1:-1], fields[2:])]
        return ((line[index], [line[x].strip() for x in fields]) for line in reader)
    else:
        fields = [slice(*x) for x  in zip(fields[:-1], fields[1:])]
        return ((i, [line[x].strip() for x in fields]) for i,line in enumerate(reader)) 

Вот тестовая программа:

import pandas
import numpy
import tempfile

# create a data frame
df = pandas.DataFrame(numpy.random.randn(100, 5))
file_ = tempfile.NamedTemporaryFile(delete=True)
file_.write(df.to_string())
file_.flush()

# specify fields
fields = [0, 3, 12, 22, 32, 42, 52]
df2 = pandas.DataFrame.from_items( fixed_width_to_items(file_.name, fields, first_column_is_index=True, ignore_first_rows=1) ).T

# need to specify the datatypes, otherwise everything is a string
df2 = pandas.DataFrame(df2, dtype=float)
df2.index = [int(x) for x in df2.index]

# check
assert (df - df2).abs().max().max() < 1E-6

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

0 голосов
/ 16 марта 2012

Что вы подразумеваете под дисплеем?Разве df['gvkey'] не предоставляет вам данные в столбце gvkey?

Если вы печатаете весь фрейм данных на консоль, посмотрите на df.to_string(), но это будет сложночитать, если у вас слишком много столбцов.Панды не будут печатать все по умолчанию, если у вас слишком много столбцов:

import pandas
import numpy 

df1 = pandas.DataFrame(numpy.random.randn(10, 3), columns=['col%d' % d for d in range(3)] )
df2 = pandas.DataFrame(numpy.random.randn(10, 30), columns=['col%d' % d for d in range(30)] )

print df1   # <--- substitute by df2 to see the difference
print
print df1['col1']
print
print df1.to_string()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...