2014-02-13 101 views
3

我有一個關於讀取csv文件的位和塊的問題。如果只是閱讀使用使用熊貓在Python中讀取csv文件塊

pd.read_csv(path,sep=';',na_values=[''],thousands='.',decimal=',',date_parser=[0]) 

文件獲得:

 EUR  1Y  2Y  3Y 
0 2013-09-25 0,198 0,307 0,485 
1 2013-09-26 0,204 0,318 0,497 
2 2013-09-27 0,204 0,306 0,487 
3 2013-09-28 0,204 0,306 0,487 
4   USD  1Y  2Y  3Y 
5 2013-09-25 0,462 0,571 0,749 
6 2013-09-26 0,468 0,582 0,761 
7 2013-09-27 0,468 0,57 0,751 
8 2013-09-28 0,468 0,57 0,751 

正如你所看到的,數據排列日期明智的,並且每個數據集是一前一後的塊(在這種情況下,美元數據是在歐元數據之後)。貨幣標籤稍微隱藏了一些東西,數據變成了一個單一的數據框。

我想什麼有兩個單獨的數據幀,

 EUR  1Y  2Y  3Y 
0 2013-09-25 0,198 0,307 0,485 
1 2013-09-26 0,204 0,318 0,497 
2 2013-09-27 0,204 0,306 0,487 
3 2013-09-28 0,204 0,306 0,487 

    USD  1Y  2Y  3Y 
0 2013-09-25 0,462 0,571 0,749 
1 2013-09-26 0,468 0,582 0,761 
2 2013-09-27 0,468 0,57 0,751 
3 2013-09-28 0,468 0,57 0,751 

也就是說,我想每個貨幣數據彼此獨立設置。

有什麼建議嗎?

回答

3

這是解決問題的另一種方法。它讀取CSV到一個單一的數據幀,然後使用比特的數據扯皮創造貨幣列:

  currency  1Y  2Y  3Y 
date          
2013-09-25  EUR 0,198 0,307 0,485 
2013-09-26  EUR 0,204 0,318 0,497 
2013-09-27  EUR 0,204 0,306 0,487 
2013-09-28  EUR 0,204 0,306 0,487 
2013-09-25  USD 0,462 0,571 0,749 
2013-09-26  USD 0,468 0,582 0,761 
2013-09-27  USD 0,468 0,57 0,751 
2013-09-28  USD 0,468 0,57 0,751 

然後你可以「分裂」根據使用groupby貨幣數據幀分成更小的DataFrames:

groups = df.groupby(['currency']) 
for key, grp in groups: 
    print(grp) 

import numpy as np 
import pandas as pd 

df = pd.read_table('data',sep=';',na_values=[''],thousands='.',decimal=',', 
        names=['date', '1Y', '2Y', '3Y']) 
mask = df['date'].str.contains('^\s*\D')    # 1 
df['currency'] = (df['date'] 
        .where(mask, np.nan)    # 2 
        .fillna(method='ffill'))   # 3 
df = df.loc[~mask]         # 4 

print(df)  

groups = df.groupby(['currency']) 
for key, grp in groups: 
    print(grp) 

  1. 使用str.contains查找以非數字開頭的df['date']中的值。這些值被假定爲貨幣。在這些行上的maskTrue

    In [120]: mask 
    Out[120]: 
    0  True 
    1 False 
    2 False 
    3 False 
    4 False 
    5  True 
    6 False 
    7 False 
    8 False 
    9 False 
    Name: date, dtype: bool 
    
  2. df['date'].where(mask, np.nan)返回一個系列,等於 df['date']其中所述掩模是True,和np.nan否則。
  3. 正向填充在nans與貨幣值

    In [123]: df['date'].where(mask, np.nan).fillna(method='ffill') 
    Out[123]: 
    0 EUR 
    1 EUR 
    2 EUR 
    3 EUR 
    4 EUR 
    5 USD 
    6 USD 
    7 USD 
    8 USD 
    9 USD 
    Name: date, dtype: object 
    
  4. 僅選擇那些行,其中該掩模是False,從而去除的標題行。
+0

真的很不錯的解決方案。實際上,我更需要內聯,因爲我最終需要將所有內容都轉換爲Excel數據透視表(因此貨幣列使事情變得更容易)。我只能得到()和[ ]作爲'mask'的輸出... – gussilago

+1

使用mask = data ['date']。str.CONTAINS('^ \ s * \ D')來代替MATCH來解決它。再次感謝@unutbu – gussilago

1

使用nrowsskiprows參數read_csv

所以對於第一數據框讀只是第4行:

eur = pd.read_csv(path,sep=';',na_values=[''],thousands='.',decimal=',',date_parser=[0], nrows=4) 

和隨後的數據幀跳過第5行:

usd = pd.read_csv(path,sep=';',na_values=[''],thousands='.',decimal=',',date_parser=[0], skiprows=5) 

應工作

+0

非常好的解決方案! @EdChum。你不會碰巧知道一個快速修復的自動化的nrows,skiprows?例如「找到非日期的首次出現 - >從那裏開始」? – gussilago

+0

您將不得不迭代閱讀csv,並且不幸的是,您沒有收到日期字符串,因此沒有內置的熊貓方法。你可以傳遞'dtype'參數來明確告訴熊貓dtype是不是列,它應該失敗,然後記錄錯誤發生的時間。 – EdChum

+0

另一種可能性是對不正確的數據幀進行切片以產生2個正確的數據幀,例如'eur = df.iloc [0:4] usd = df.iloc [5:10]'例如,您必須重命名美元df雖然 – EdChum