H5py, объединить совпавшие строки из огромного файла hdf5 в меньшие наборы данных - PullRequest
0 голосов
/ 31 марта 2020

У меня есть два огромных файла hdf5, каждый с индексом идентификаторов, каждый из которых содержит различную информацию о каждом из этих идентификаторов.

Я прочитал один файл в небольшом замаскированном наборе данных (данных), используя только выберите несколько идентификаторов. Теперь я хочу добавить к набору данных, используя информацию об этих выбранных идентификаторах из одного столбца ('a') второго файла hdf5 (s_data).

В настоящее время мне приходится читать весь 2-й файл hdf5 и выберите идентификаторы, которые соответствуют, в соответствии с:

for i in range(len(data['ids'])):
        print(i)
        data['a'][i] = s_data['a'][s_data['ids'] == data['ids'][i]]

Теперь для 190 миллионов идентификаторов это занимает слишком много времени. Есть ли более простой способ сопоставить их? Я думаю о соединении в стиле pandas, однако я не могу найти способ для этого работать с наборами данных h5py.

Заранее большое спасибо!

1 Ответ

0 голосов
/ 31 марта 2020

Рассматривали ли вы PyTables? Это еще один Python пакет для чтения файлов HDF5. Он имеет быстрые алгоритмы поиска на основе OPSI (оптимизированные частично отсортированные индексы). Использование метода .read_where() с условием поиска упростит процесс поиска и должно быть быстрее, чем h5py.

Ваш вопрос похож на другой, на который я ответил на прошлой неделе о поиске дубликатов. Вы можете прочитать мой ответ здесь:
Pytables дублирует строки по 2,5 гига

Перед поиском я бы получил массив уникальных значений из поля 'ids' в 'data' для использования в состоянии .read_where() для поиска 'sdata'. Если я понимаю ваш процесс и данные, код будет выглядеть так:

import tables as tb
# need to open HDF5 files  
h5f1 = tb.File('yourfile1.h5','r')
h5f2 = tb.File('yourfile2.h5','r')
# define data and sdata datasets:
data  = h5f1.root.data
sdata = h5f2.root.sdata

# Step 1: Get a Numpy array of the 'ids' field/column from data DS: 
ids_arr = data.read(field='ids')
# Step 2: Get new array with unique values only: 
uids_arr = np.unique(ids_arr)     

#Or, combine steps 1 and 2 into one line: 
uids_arr = np.unique(data.read(field='ids')) 

# Step 3a: Loop on rows of unique id values 
for id_test in uids_arr :

# Step 3b: Get an array with all rows that match this id value, 
#          Only returns values in field 'a' 
     match_row_arr = sdata.read_where('ids==id_test',field='a')
...