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 合并。要获得完整结果,您需要连接结果。
我想在 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 合并。要获得完整结果,您需要连接结果。