簡體   English   中英

如何在 Pandas 中讀取固定寬度格式的文本文件?

[英]How do I read a fixed width format text file in pandas?

我剛剛接觸了熊貓,正在研究如何讀取文件。 該文件來自 WRDS 數據庫,是可追溯到 1960 年代的 SP500 成分列表。 我檢查了文件,無論我如何使用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)

上面的輸出塊是什么意思? 任何事情都會有所幫助。

pandas.read_fwf()已在 pandas 0.7.3( 2012 年 4 月)中添加以處理固定寬度的文件。

  1. API參考

  2. 其他問題的一個例子

韋斯在一封電子郵件中回復了我。 干杯。

這是一個固定寬度格式的文件(不像往常那樣用逗號或制表符分隔)。 我意識到熊貓沒有像 R 那樣的固定寬度閱讀器,盡管可以很容易地塑造它。 我會看看我能做什么。 同時,如果您可以以另一種格式導出數據(例如 csv——真正以逗號分隔),您將能夠使用 read_csv 讀取它。 我懷疑使用一些 unix 魔法可以將 FWF 文件轉換為 CSV 文件。

我建議關注 github 上的問題,因為您的電子郵件即將從我的收件箱中消失:)

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

最好的,韋斯

你說的顯示是什么意思? df['gvkey']不是給你 gvkey 列中的數據嗎?

如果您所做的是將整個數據框打印到控制台,請查看df.to_string() ,但如果您有太多列,則很難閱讀。 如果列太多,Pandas 默認不會打印整個內容:

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()

用戶,如果您現在需要處理固定格式,您可以使用以下內容:

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

如果您現在需要它,這應該可以解決問題,但請記住,上面的函數非常簡單,特別是它對數據類型沒有任何作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM