Попытка загрузить таблицу hdf5 с dataframe.to_hdf, прежде чем я умру от старости - PullRequest
0 голосов
/ 31 мая 2019

Звучит так, что на самом деле должно быть ДЕЙСТВИТЕЛЬНО легко ответить с помощью Google, но я считаю невозможным ответить на большинство моих нетривиальных вопросов о пандах / таблицах таким образом.Все, что я пытаюсь сделать, это загрузить около 3 миллиардов записей из примерно 6000 различных файлов CSV в одну таблицу в одном файле HDF5.Это простая таблица, 26 полей, смесь строк, чисел с плавающей точкой и целых.Я загружаю файлы CSV с помощью df = pandas.read_csv () и добавляю их в мой файл hdf5 с помощью df.to_hdf ().Я действительно не хочу использовать df.to_hdf (data_columns = True), потому что похоже, что для df.to_hdf это займет около 20 дней против 4 дней (data_columns = False).Но, очевидно, когда вы используете df.to_hdf (data_columns = False), вы получаете кучу мусора, из которого вы даже не можете восстановить структуру таблицы (или, как мне кажется, необразованный глаз).Только столбцы, которые были определены в списке min_itemsize (4 строковых столбца), могут быть идентифицированы в таблице hdf5, остальные выгружаются по типу данных в values_block_0 через values_block_4:

table = h5file.get_node ('/tbl_main / table ') print (table.colnames) [' index ',' values_block_0 ',' values_block_1 ',' values_block_2 ',' values_block_3 ',' values_block_4 ',' str_col1 ',' str_col2 ',' str_col3 ',' str_4']

И любой запрос, такой как df = pd.DataFrame.from_records (table.read_where (условие)), завершается с ошибкой «Исключение: данные должны быть одномерными»

Так что мои вопросы: (1) Мне действительно нужно использовать «data_columns = True», что занимает 5 раз дольше?Я ожидал сделать быструю загрузку и затем индексировать только несколько столбцов после загрузки таблицы.(2) Что именно это за куча мусора, которую я получаю, используя "data_columns = False"?Хорошо ли это для чего-нибудь, если мне нужно вернуть свою таблицу со столбцами с запросами?Это хорошо для чего-либо вообще?

1 Ответ

0 голосов
/ 31 мая 2019

Вот как вы можете создать файл HDF5 из данных CSV, используя pytables.Вы также можете использовать аналогичный процесс для создания файла HDF5 с h5py.

  1. Используйте цикл для чтения файлов CSV с np.genfromtxt в массив np.
  2. После чтенияВ первый CSV-файл запишите данные методом .create_table(), ссылаясь на массив np, созданный на шаге 1.
  3. Для дополнительных CSV-файлов запишите данные с помощью метода .append(), ссылаясь на массив np, созданный на шаге 1

Конец цикла
Обновлено 6/2/2019 для чтения поля даты (мм / дд / ГГГ) и преобразования в datetime объект.Обратите внимание на изменения genfromtxt() аргументов!Используемые данные добавляются под обновленным кодом.

import numpy as np   
import tables as tb
from datetime import datetime
csv_list = ['SO_56387241_1.csv', 'SO_56387241_2.csv' ]

my_dtype= np.dtype([ ('a',int),('b','S20'),('c',float),('d',float),('e','S20') ])

with tb.open_file('SO_56387241.h5', mode='w') as h5f:

for  PATH_csv in csv_list:
    csv_data = np.genfromtxt(PATH_csv, names=True, dtype=my_dtype, delimiter=',', encoding=None)
    # modify date in fifth field 'e'   
    for row in csv_data :
        datetime_object = datetime.strptime(row['my_date'].decode('UTF-8'), '%m/%d/%Y' )
        row['my_date'] = datetime_object

    if h5f.__contains__('/CSV_Data') :
        dset = h5f.root.CSV_Data
        dset.append(csv_data)

    else:
        dset = h5f.create_table('/','CSV_Data', obj=csv_data)

    dset.flush()

h5f.close()

Данные для тестирования:

SO_56387241_1.csv:
my_int,my_str,my_float,my_exp,my_date
0,zero,0.0,0.00E+00,01/01/1980
1,one,1.0,1.00E+00,02/01/1981
2,two,2.0,2.00E+00,03/01/1982
3,three,3.0,3.00E+00,04/01/1983
4,four,4.0,4.00E+00,05/01/1984
5,five,5.0,5.00E+00,06/01/1985
6,six,6.0,6.00E+00,07/01/1986
7,seven,7.0,7.00E+00,08/01/1987
8,eight,8.0,8.00E+00,09/01/1988
9,nine,9.0,9.00E+00,10/01/1989


SO_56387241_2.csv:
my_int,my_str,my_float,my_exp,my_date
10,ten,10.0,1.00E+01,01/01/1990
11,eleven,11.0,1.10E+01,02/01/1991
12,twelve,12.0,1.20E+01,03/01/1992
13,thirteen,13.0,1.30E+01,04/01/1993
14,fourteen,14.0,1.40E+01,04/01/1994
15,fifteen,15.0,1.50E+01,06/01/1995
16,sixteen,16.0,1.60E+01,07/01/1996
17,seventeen,17.0,1.70E+01,08/01/1997
18,eighteen,18.0,1.80E+01,09/01/1998
19,nineteen,19.0,1.90E+01,10/01/1999
...