在Python中合并具有数百万行的两个表

2024-04-23 23:41:17 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
1条回答
网友
1楼 · 发布于 2024-04-23 23:41:17

这有点假科迪什,但我认为应该相当快。

直接基于磁盘的合并,所有表都在磁盘上。这个 关键是你不是在做选择本身,只是索引 通过启动/停止进入桌子,这相当快。

在B中选择符合条件的行(使用a的id)不会 非常快,因为我认为它可能会将数据带入Python空间 而不是在内核中搜索(我不确定,但您可能需要 更多关于pytables.org的信息,请参阅内核优化部分。 有一种方法可以判断它是否在内核中)。

如果你能做到,这是一个非常平行的问题(只是不要写 从多个进程将结果发送到同一文件。pytables对此不是写安全的)。

请参阅this answer以获取有关如何执行联接操作实际上是“内部”联接的注释。

对于您的合并操作,我认为您可以使用标准的pandas join 这是相当有效的(在记忆中)。

另一个选择(取决于A的“大”程度)可能是将A分成两部分(索引相同),在第一个表中使用较小的(可能使用单个列);而不是存储合并结果本身,而是存储行索引;然后可以提取所需的数据(类似于使用索引器和take)。见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)

相关问题 更多 >