2014-05-20 45 views
4

最終的解決方案是使用read_csv的「轉換器」參數,並在將每個值添加到DataFrame之前檢查每個值。最後,在超過80GB的原始數據中只有2個值被破壞。追加到HDFStore失敗,「無法匹配現有表結構」

的參數如下:

converters={'XXXXX': self.parse_xxxxx} 

和小靜態輔助方法是這樣的:

@staticmethod 
def parse_xxxxx(input): 
    if not isinstance(input, float): 
     try: 
      return float(input) 
     except ValueError: 
      print "Broken Value: ", input 
      return float(0.0) 
    else: 
     return input 

嘗試讀取約將40GB + csv數據轉換爲HDF文件我遇到了一個令人困惑的問題。閱讀1GB後的整個過程失敗,出現以下錯誤

File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 658, in append 
    self._write_to_group(key, value, table=True, append=True, **kwargs) 
    File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 923, in write_to_group 
    s.write(obj = value, append=append, complib=complib, **kwargs) 
    File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 2985, in write **kwargs) 
    File "/usr/lib/python2.7/dist-packages/pandas/io/pytables.py", line 2675, in create_axes 
    raise ValueError("cannot match existing table structure for [%s] on appending data" % items) 
ValueError: cannot match existing table structure for [Date] on appending data 

的read_csv調用我用的是如下:

pd.io.parsers.read_csv(filename, sep=";|\t", compression='bz2', index_col=False, header=None, names=['XX', 'XXXX', 'Date', 'XXXXX'], parse_dates=[2], date_parser=self.parse_date, low_memory=False, iterator=True, chunksize=self.input_chunksize, dtype={'Date': np.int64}) 

爲什麼新塊的「日期」欄不適合現有的colum當我明確地設置dtypte爲int64?

Thx爲您的幫助!

下面是解析日期的功能:

@staticmethod 
def parse_date(input_date): 
     import datetime as dt 
     import re 

     if not re.match('\d{12}', input_date): 
      input_date = '200101010101' 

     timestamp = dt.datetime.strptime(input_date, '%Y%m%d%H%M') 
     return timestamp 

以下一些傑夫的技巧後,我可以提供我的問題的進一步細節。這裏是我使用加載BZ2編碼的文件的整個代碼:

iterator_data = pd.io.parsers.read_csv(filename, sep=";|\t", compression='bz2', index_col=False, header=None, 
               names=['XX', 'XXXX', 'Date', 'XXXXX'], parse_dates=[2], 
               date_parser=self.parse_date, iterator=True, 
               chunksize=self.input_chunksize, dtype={'Date': np.int64}) 
for chunk in iterator_data: 
    self.data_store.append('huge', chunk, data_columns=True) 
    self.data_store.flush() 

CSV文件遵循以下模式:{STRING}; {STRING}; {STRING} \噸{INT}

ptdump的輸出-av要求的輸出文件如下:

ptdump -av datastore.h5 
/(RootGroup) '' 
    /._v_attrs (AttributeSet), 4 attributes: 
    [CLASS := 'GROUP', 
    PYTABLES_FORMAT_VERSION := '2.0', 
    TITLE := '', 
    VERSION := '1.0'] 
/huge (Group) '' 
    /huge._v_attrs (AttributeSet), 14 attributes: 
    [CLASS := 'GROUP', 
    TITLE := '', 
    VERSION := '1.0', 
    data_columns := ['XX', 'XXXX', 'Date', 'XXXXX'], 
    encoding := None, 
    index_cols := [(0, 'index')], 
    info := {'index': {}}, 
    levels := 1, 
    nan_rep := 'nan', 
    non_index_axes := [(1, ['XX', 'XXXX', 'Date', 'XXXXX'])], 
    pandas_type := 'frame_table', 
    pandas_version := '0.10.1', 
    table_type := 'appendable_frame', 
    values_cols := ['XX', 'XXXX', 'Date', 'XXXXX']] 
/huge/table (Table(167135401,), shuffle, blosc(9)) '' 
    description := { 
    "index": Int64Col(shape=(), dflt=0, pos=0), 
    "XX": StringCol(itemsize=16, shape=(), dflt='', pos=1), 
    "XXXX": StringCol(itemsize=16, shape=(), dflt='', pos=2), 
    "Date": Int64Col(shape=(), dflt=0, pos=3), 
    "XXXXX": Int64Col(shape=(), dflt=0, pos=4)} 
    byteorder := 'little' 
    chunkshape := (2340,) 
    autoIndex := True 
    colindexes := { 
    "Date": Index(6, medium, shuffle, zlib(1)).is_CSI=False, 
    "index": Index(6, medium, shuffle, zlib(1)).is_CSI=False, 
    "XXXX": Index(6, medium, shuffle, zlib(1)).is_CSI=False, 
    "XXXXX": Index(6, medium, shuffle, zlib(1)).is_CSI=False, 
    "XX": Index(6, medium, shuffle, zlib(1)).is_CSI=False} 
    /huge/table._v_attrs (AttributeSet), 23 attributes: 
    [XXXXX_dtype := 'int64', 
    XXXXX_kind := ['XXXXX'], 
    XX_dtype := 'string128', 
    XX_kind := ['XX'], 
    CLASS := 'TABLE', 
    Date_dtype := 'datetime64', 
    Date_kind := ['Date'], 
    FIELD_0_FILL := 0, 
    FIELD_0_NAME := 'index', 
    FIELD_1_FILL := '', 
    FIELD_1_NAME := 'XX', 
    FIELD_2_FILL := '', 
    FIELD_2_NAME := 'XXXX', 
    FIELD_3_FILL := 0, 
    FIELD_3_NAME := 'Date', 
    FIELD_4_FILL := 0, 
    FIELD_4_NAME := 'XXXXX', 
    NROWS := 167135401, 
    TITLE := '', 
    XXXX_dtype := 'string128', 
    XXXX_kind := ['XXXX'], 
    VERSION := '2.6', 
    index_kind := 'integer'] 

了很多額外的調試我得到了下面的錯誤後:

ValueError: invalid combinate of [values_axes] on appending data [name->XXXX,cname->XXXX,dtype->int64,shape->(1, 10)] vs current table [name->XXXX,cname->XXXX,dtype->string128,shape->None] 

然後我試圖通過添加修改read_csv調用,這樣給力的XXXX列類型正確解決這個問題,但剛剛收到了同樣的錯誤:

dtype={'XXXX': 's64', 'Date': dt.datetime}) 

read_csv忽略了D型設置或者我在這裏錯過了什麼?

當了10 CHUNKSIZE讀取數據的最後2 chunk.info()調用提供以下的輸出:

Int64Index: 10 entries, 0 to 9 
Data columns (total 4 columns): 
XX   10 non-null values 
XXXX  10 non-null values 
Date  10 non-null values 
XXXXX  10 non-null values 
dtypes: datetime64[ns](1), int64(1), object(2)<class 'pandas.core.frame.DataFrame'> 
Int64Index: 10 entries, 0 to 9 
Data columns (total 4 columns): 
XX   10 non-null values 
XXXX  10 non-null values 
Date  10 non-null values 
XXXXX  10 non-null values 
dtypes: datetime64[ns](1), int64(2), object(1) 

我使用的是熊貓版0.12.0

+0

很好地顯示了現有的表格和你試圖存儲的示例(顯示df.info()),熊貓版本以及 – Jeff

+0

http://stackoverflow.com/questions/15488809/how-to-trouble- shoot-hdfstore-exception-can not-find-the-correct-atom-type可能會幫助你排除故障 – Jeff

+0

也會顯示不會精確的讀寫代碼 – Jeff

回答

5

確定你有幾個問題:

  • 指定dtypes時

    傳遞給read_csv,他們必須numpy的dtypes;和字符串dtypes轉換爲object dtype(所以s64不會做任何事情)。也沒有datetime,這就是使用parse_dates

  • 您在不同的塊dtypes是不同的,這是第一你有2個int64列和1 object,而第二個有1 int64和2 object。這是你的問題。 (我認爲這個錯誤信息可能會有些混亂,這是IIRC在更新版本的熊貓中修復的)。

所以,你需要使每個塊中的你的dty都一致。您可能在該特定列中混合了數據。一種方法是指定dtype = { column_that_is_bad : 'object' }。另一種方法是使用convert_objects(convert_numeric=True) ON THAT列強制所有非數字值爲nan(這也會將列的dtype更改爲float64)。

+0

即使將dtype更改爲:dtype = {'XX':'object','XXXX':'object','Date':'object','XXXXX':'uint64'})升級到Pandas 0.13.1我得到這個: ValueError:在追加數據[名稱 - > XXXXX,cname-> XXXXX,dtype-> float64,形狀 - >(1,10000000)]與當前表[名稱 - > XXXXX]上的[values_axes]無效組合, cname-> XXXXX,dtype-> int64,shape-> None] – FrozenSUSHI

+0

在將它們寫入HDF之前,需要先符合這些dtypes,然後在寫入它們之前查看每個塊的df.dtypes。有些數據會改變它們(例如,您可能在一個數據庫中缺少值,但在另一個數據庫中可能缺失)你需要強制適當的格式。 – Jeff

+0

混合dtypes也是我的問題。這個令人困惑的錯誤信息仍然存在於hdf的pandas 0.20.3中 – ClimbsRocks