Это немного псевдокодово, но я думаю, должно быть довольно быстро.
Простое слияние на диске со всеми таблицами на диске. Суть в том, что вы не делаете выборку как таковую, а просто индексируете таблицу через start/stop, что довольно быстро.
Выбор строк, соответствующих критерию в B (с использованием идентификаторов A), не будет очень быстрым, потому что я думаю, что это может быть перенос данных в пространство Python, а не поиск в ядре (я не уверен, но вы можете захотеть чтобы узнать больше на pytables.org в разделе оптимизации в ядре.Есть способ определить, будет ли это в ядре или нет).
Кроме того, если вы готовы к этому, это очень параллельная проблема (просто не записывайте результаты в один и тот же файл из нескольких процессов. pytables для этого небезопасен для записи).
См. это answer для комментария о том, как выполнение операции соединения на самом деле будет «внутренним» соединением.
Я думаю, что для вашей операции merge_a_b вы можете использовать стандартное соединение панд, которое довольно эффективно (когда в памяти).
Еще один вариант (в зависимости от того, насколько «большой» A) может состоять в том, чтобы разделить A на 2 части (которые индексируются одинаково), используя меньший (возможно, использовать один столбец) в первой таблице; вместо сохранения результатов слияния как таковых сохраните индекс строки; позже можно вытащить нужные данные (вроде как с помощью индексатора и взять). См. http://pandas.pydata.org/pandas-docs/stable/io.html#multiple-table-queries
A = HDFStore('A.h5')
B = HDFStore('B.h5')
nrows_a = A.get_storer('df').nrows
nrows_b = B.get_storer('df').nrows
a_chunk_size = 1000000
b_chunk_size = 1000000
def merge_a_b(a,b):
# Function that returns an operation on passed
# frames, a and b.
# It could be a merge, join, concat, or other operation that
# results in a single frame.
for a in xrange(int(nrows_a / a_chunk_size) + 1):
a_start_i = a * a_chunk_size
a_stop_i = min((a + 1) * a_chunk_size, nrows_a)
a = A.select('df', start = a_start_i, stop = a_stop_i)
for b in xrange(int(nrows_b / b_chunk_size) + 1):
b_start_i = b * b_chunk_size
b_stop_i = min((b + 1) * b_chunk_size, nrows_b)
b = B.select('df', start = b_start_i, stop = b_stop_i)
# This is your result store
m = merge_a_b(a, b)
if len(m):
store.append('df_result', m)
person
Jeff
schedule
31.01.2013