2017-04-17 83 views
0

這裏是熊貓的新功能。 我有一個叫做all_invoice的熊貓DataFrame,只有一列叫做'whole_line'。使用read_fwf函數調用熊貓系列函數

all_invoice中的每一行都是固定寬度的字符串。我需要從all_invoice使用read_fwf一個新的DataFrame。 我有一個看起來像這樣一個有效的解決方案:

invoice = pd.DataFrame() 
for i,r in all_invoice['whole_line'].iteritems(): 
    temp_df = pd.read_fwf(StringIO(r), colspecs=in_specs, 
          names=in_cols, converters=in_convert) 
    invoice = invoice.append(temp_df, ignore_index = True) 

in_specsin_colsin_convert已經在我的腳本前面定義。

所以這個解決方案的工作,但是非常緩慢。對於具有85列的18K行,這部分代碼需要大約6分鐘才能執行。我希望有一個更優雅的解決方案,它不涉及遍歷DataFrame或Series中的行,並使用apply函數調用read_fwf以使其更快。所以,我想:

invoice = all_invoice['whole_line'].apply(pd.read_fwf, colspecs=in_specs,names=in_cols, converters=in_convert) 

我回溯的尾部看起來像:

OSError: [Errno 36] File name too long: 

此之後冒號是傳遞給read_fwf方法的字符串。我懷疑這是因爲read_fwf需要一個文件路徑或緩衝區。在我的工作(但很慢)的代碼中,我可以調用字符串上的StringIO()來使其成爲一個緩衝區,但我不能用apply函數來實現。讚賞任何幫助獲得應用工作或其他方式使用整個系列/ df上的read_fwf以避免迭代行,這是值得讚賞的。謝謝。

+0

你能不能此列保存到一個文件,然後使用一個'read_fwf'調用一次閱讀完所有的行? – gereleth

+0

我寧願不要在read_fwf之前將文件寫回磁盤。感謝您的建議。 – okyere

回答

0

您是否嘗試過只是做:

invoice = pd.read_fwf(filename, colspecs=in_specs, 
         names=in_cols, converters=in_convert) 
+0

我沒有文件作爲輸入。相反,原始文件中的行保存在我的輸入數據框中。 – okyere

+0

您是否擁有all_invoice構建的文件? – Grr

+0

得到該文件,但它有3種不同類型的行(行);發票,供應商,purchase_order。在前面的腳本中,我使用pd.read_table將整個文件讀入df,然後根據20到22的值將該df分爲3個不同的數據框。 all_df = pd.read_table('MARCHGRIEF.TXT',名稱= ['whole_line'],標題=無)。 all_invoice = all_df [all_df.whole_line.str [20:22] ==「IN」] 供應商和寶的類似。不幸的是,read_fwf不能讓我根據條件解析一行。我需要這樣,因爲每種類型的行/行供應商都有不同的結構。 – okyere