当前位置: 首页 > 面试题库 >

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

公子昂
2023-03-14
问题内容

我正在使用Python进行一些数据分析。我有两个表,第一个(叫它“ A”)有1000万行和10列,第二个(“
B”)有7300万行和2列。他们有1个具有共同ID的列,我想根据该列将两个表相交。特别是我想要表的内部联接。

我无法将表B作为pandas数据框加载到内存中,以在pandas上使用常规合并功能。我尝试通过读取表B上的文件的块,将每个块与A相交,并将这些交集连接起来(内部联接的输出)。这在速度上还可以,但时不时地给我带来问题,并吐出分段错误……不是很好。很难重现此错误,但是会在两台不同的计算机(Mac
OS X v10.6(Snow Leopard)和UNIX,Red Hat Linux)上发生。

我最终通过将表B写入磁盘,然后遍历表A并从表B中选择匹配的行来尝试使用Pandas和PyTables的组合。最后一个选项有效,但是速度很慢。缺省情况下,已经在pytables的表B上建立了索引。

我该如何解决这个问题?


问题答案:

这是一个伪伪鳕鱼,但我认为应该很快。

基于磁盘的直接合并,磁盘上的所有表。关键是您本身并没有做选择,只是通过启动/停止索引到表中,这非常快。

选择满足B中条件的行(使用A的id)不会很快,因为我认为这可能会将数据带入Python空间而不是内核内搜索(我不确定,但是您可能想要在内核优化部分中进一步研究pytables.org。有一种方法可以确定它是否将在内核中。

同样,如果您愿意的话,这是一个非常并行的问题(只是不要将结果从多个进程写入同一文件。pytables对此不安全)。

对于您的merge_a_b操作,我认为您可以使用效率很高的标准pandas连接(在内存中)。

另一种选择(取决于A的大小)可能是将A分成两部分(索引相同),并在第一个表中使用较小的(可能使用单列)。而不是存储合并结果本身,而是存储行索引;之后,您可以提取所需的数据(有点像使用索引器并获取数据)。

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)


 类似资料:
  • 我有数百万个不同标题的csv文件,我想把它们合并到一个大数据框中。 我的问题是我尝试过的解决方案有效,但太慢了!顺便说一句,我可以访问Sparklyr在我的实验室中处理多节点集群,这个大数据工具会有帮助吗? 文件如下所示: 文件1 校长1,校长3,校长5 a、 b,c 文件2 校长4,校长2 e、 f 文件3 校长2,校长6 a, c 我想把它们合并成: 校长1,校长2,校长3,校长4,校长5,校

  • 问题内容: 我有两个表(表A和表B)。 它们具有不同的列数-假设表A具有更多列。 如何合并这两个表,并为表B没有的列获取空值? 问题答案: 为具有较少列的表添加额外的列作为null

  • 问题内容: 我可以在其他具有相同列名的数据框的右边追加一个数据框吗 问题答案: 您可以像这样连接两个数据框。 如果您正在寻找联盟,则可以执行以下操作。 Spark 2.0,已重命名为

  • 问题内容: 我肯定在这里错过了一些简单的事情。尝试在熊猫中合并具有相同列名的两个数据框,但右侧的数据框具有一些左侧没有的列,反之亦然。 我试着加入外部联接: 但这产生了: 我还指定了一个要连接的单列(例如on =“ id”),但是它复制了除“ id”以外的所有列,例如attr_1_x,attr_1_y,这并不理想。我也将整个列列表(有很多)传递给了“ on”: 产生: 我想念什么?我想获得一个带有

  • 问题内容: 我最近发现并修复了我正在处理的站点中的错误,该错误导致表中有数百万行重复的数据行,即使没有行也将非常大(仍然有数百万行)。我可以轻松找到这些重复的行,并可以运行一个删除查询来杀死它们。问题是试图一次删除这么多行会长时间锁定表,如果可能的话,我想避免这种情况。我可以看到摆脱这些行而又不占用站点(通过锁定表)的唯一方法是: 编写一个脚本,该脚本将循环执行数千个较小的删除查询。从理论上讲,这

  • 每当我收到消息时,我都想从数据库中读取,可能会返回数百万行,然后我想将这些行传递到流中。这在Flink被认为是良好的做法吗? 编辑: 背景:我想动态运行报告。db基本上是一个巨大的窗口。该报告基于该窗口实时数据。该报告具有高度的可定制性,因此很难预先处理结果或定义管道。 我今天使用的是vanilla java,管道大致是这样的:报告定义-