Pandas:比较大数据框和小数据框

Pandas: compare huge dataframe with smaller dataframe

我想在 pandas 中比较两个数据帧,一个太大而无法放入内存,另一个较小但适合内存。

dfSmall:
cat1    cat2
foo     bar
foo     tiger
foo     spam
bar     spam
(5000 rows)

dfLarge:
cat1    cat2    cat3
foo     dog     green
foo     tiger   blue
foo     snake   green
foo     bird    pink
bar     dog     orange
...
(>1 million rows)

我用过dask.dataframe(dd.merge),但是耗时长,折腾多,而且好像效率低,因为我的一个df会装进内存。我还使用了 pandas.read_table 和设置的块大小,但只是为了修改文件本身,而不是将它与另一个文件进行比较。

更复杂的是我希望输出文件只保留匹配 两个 列的行 - cat1 和 cat2。在上面的示例中,输出将只有一行 - foo cat,因为这是两列匹配的唯一一行。如果不可能匹配两列,我不介意只能匹配一列的解决方案,我只需要修改数据框以将 cat1/cat2 合并到一列中。

dfOutput:
cat1    cat2    cat3
foo     tiger   blue

使用 read_table with chunksize,假设您首先创建一个函数,将一个块与较小的 table:

合并
dfSmall = pd.read_table(small_path, ...)

def merge_it(c):
    return dfSmall.merge(c, on=['cat1', 'cat2'], suffixes=('', '_y'))[['cat1', 'cat2', 'cat3']]

请注意,合并时,pandas 会在公共列上添加后缀。上面的代码表示不向块的列添加后缀(即元组中的 '' ),并取 'cat1', 'cat2', 'cat3'.

然后你可以连接较大的块合并,像这样:

pd.concat([merge_it(c) for c in pd.read_table(large_path, ..., chunksize=100000)])

请注意,对于每个块,您都会将其与小 DataFrame 合并。要获得完整结果,您需要连接结果。