Не удается открыть файл HDF5 размером больше памяти ValueError

У меня много файлов такси Нью-Йорка в формате CSV от nyc.gov, один .csv = год-месяц. Я беру примерно 15 csv и делаю из них HDF5:

import h5py
import pandas as pd
import os 
import glob
import numpy as np

import vaex
from tqdm import  tqdm_notebook as tqdm

#hdf = pd.HDFStore('c:/Projekty/H5Edu/NYCTaxi/NYCTaxi.hp')
#df1 = pd.read_csv('path nejake csvcko')
#hdf.put('DF1', df1, format = 'table', data_columns = True)


csv_list = np.sort(np.array(glob.glob('G:\\NYCTaxi\\*.csv')))[::-1]

csv_list = csv_list[20:39]

output_dir = 'c:\\Datasety\\YelowTaxi\\DataH5\\'

for file in tqdm(csv_list, leave=False, desc='Converting to hdf5...'):
    # Setting up the files, and directories
    #zip_file = ZipFile(file)
    output_file = file.split('\\')[-1][:-3]+'hdf5'
    output = output_dir + output_file
    #output = output_file
    
    # Check if a converted file already exists: if it does skip it, otherwise read in the raw csv and convert it
    if (os.path.exists(output) and os.path.isfile(output)):
        pass
    else:
        # Importing the data into pandas 
        #pandas_df = [pd.read_csv(file, index_col=None, header=0)][0]
        pandas_df = [pd.read_csv(file, index_col=None, header=0, low_memory=False)][0]
        # Rename some columns to match the more well known dataset from 
        # http://stat-computing.org/dataexpo/2009/the-data.html
        

        # Importing the data from pandas to vaex
        vaex_df = vaex.from_pandas(pandas_df, copy_index=False)
        
        # Export the data with vaex to hdf5
        vaex_df.export_hdf5(path=output, progress=False)

Далее делаю один большой HDF5:

import re
import glob
import vaex
import numpy as np

def tryint(s):
    try:
        return int(s)
    except:
        return s

def alphanum_key(s):
    """ Turn a string into a list of string and number chunks.
        "z23a" -> ["z", 23, "a"]
    """
    return [ tryint(c) for c in re.split('([0-9]+)', s) ]

hdf5_list = glob.glob('c:\\Datasety\\YelowTaxi\\DataH5\\*.hdf5')
hdf5_list.sort(key=alphanum_key)
hdf5_list = np.array(hdf5_list)

#assert len(hdf5_list) == 3, "Incorrect number of files"

# This is an important step
master_df = vaex.open_many(hdf5_list)

# exporting
#master_df.export_hdf5(path='c:\\Datasety\\YelowTaxi\\DataH5\\Spojene.hd5', progress=True)
master_df.export_hdf5(path='c:\\Datasety\\YelowTaxi\\DataH5\\Spojene.hdf5', progress=True)

Пока все в порядке, могу открыть выходной файл Spojene.hdf5.

Затем я добавляю новый .csv в Spojene.hdf5:

for file in csv_list:
#file = csv_list[0]
    df2 = pd.read_csv(file, index_col=None, header=0, low_memory=False)
    filename = 'c:\\Datasety\\YelowTaxi\\DataH5\\Spojene.hdf5'
    df2.to_hdf(filename, 'data', append=True)

Но когда я добавляю новый .csv в Spojene.hdf5, я не могу его открыть:

df = vaex.open('c:\\Datasety\\YelowTaxi\\DataH5\\Spojene.hdf5')

ValueError: первые столбцы имеют длину 289184484, а таблица столбцов - 60107988.

Сообщение об ошибке

Pls, что я могу сделать?


person 314mip    schedule 10.04.2021    source источник
comment
Размер файла не должен быть проблемой. Обычно открываются файлы HDF5, размер которых превышает размер ОЗУ (по крайней мере, с h5py, PyTables, C, C ++ и FORTRAN). В этом весь смысл HDF5. Проверьте свой 2-й процесс - он отличается от 1-го. Когда вы создаете Spojene.hdf5, вы загружаете данные с помощью pd.read_csv(), затем конвертируете в vaex с помощью .from_pandas(), затем .export_hdf5(). Во второй раз вы загружаете с помощью pd.read_csv(), но добавляете данные в Spojene.hdf5 напрямую с помощью df2.to_hdf(). Разные процессы - разные результаты? Изучите схему данных для каждого процесса. Может быть, они непоследовательны.   -  person kcw78    schedule 10.04.2021


Ответы (1)


Я думаю, это связано с тем, как pandas создает файлы hdf5. Согласно vaex документация, вы не можете открыть файл HDF5 с помощью vaex, если он был создан с помощью метода to_hdf pandas. Я предполагаю, что это то же самое, если вы добавите к существующему файлу HDF5.

Чтобы избежать этой ошибки, вы можете повторно использовать свою логику, где вы конвертируете фрейм данных pandas в фрейм данных vaex, экспортируете его в HDF5, а затем используете open_many. Примерно так должно работать:

main_hdf5_file_path = "c:\\Datasety\\YelowTaxi\\DataH5\\Spojene.hdf5"

hdf5_files_created = []
for file in csv_list:
   hdf5_file = file.replace(".csv", ".hdf5")
   # from_csv can take additional parameters to forward to pd.read_csv
   # You can also use convert=True to convert it automatically to hdf5 without the export_hdf5
   # Refer to https://vaex.readthedocs.io/en/docs/api.html#vaex.from_csv
   df = vaex.from_csv(file) 
   df.export_hdf5(hdf5_file)
   hdf5_files_created.append(hdf5_file)

hdf5_to_read = hdf5_files_created + [main_hdf5_file_path]

final_df = vaex.open_many(hdf5_to_read)
final_df.export_hdf5(main_hdf5_file_path)
person M. Perier--Dulhoste    schedule 12.04.2021