如何使用 Python 比较太大而无法放入内存的数据帧?

How do I compare dataframes that are too big to fit in memory using Python?

我有潜在的大数据框,大约 10 列和 1e6 行,具有不同的维度。假设行在两个数据框中都是唯一的。由于无法将这些数据帧加载到内存中,我如何找到一个数据帧中存在于另一个数据帧中的所有行?我目前只处理较小的数据帧,但我必须尽快解决这个问题。

我非常喜欢使用 pandas,但如果有明显的好处,我愿意使用不同的包(xarray?)。如果您推荐不同的包,请提供一些进行比较的代码。

以下是我如何与适合内存的 pandas 数据帧进行比较:

import pandas as pd

def row_intersection(df1, df2):
    noNA = df2.fillna(0)
    return df1.fillna(0).apply(lambda x: (noNA==x).all(axis=1).any(), axis=1)

a = DataFrame({'a':[ 1, 2, 3, 4],
               'b':[ 1, pd.NA, 13, 14],
               'c':['w', 'x', 'y', 'z']})
b = DataFrame({'a':[3, 2, 4],
               'b':[1, pd.NA, 14],
               'c':['y', 'x', 'z']})

# there are equivalent rows in both dataframes:
print('row comparison:',(b.fillna(0).loc[[1,2]].values == a.fillna(0).loc[[1,3]].values).all())


print(row_intersection(a, b))

输出:

row comparison: True
0    False
1     True
2    False
3     True
dtype: bool

此外,如果有一种快速的方法可以一次获得两个帧中所有行的交集,我很想知道。现在我分两步这样做:

a_in_b = row_intersection(a, b)
b_in_a = row_intersection(b, a)

更简单的方法是使用合并和映射 -> 合并有一个 indicator 参数,以确定哪些行匹配:

(a.merge(b, indicator = True, how = 'left')['_merge']
  .map(lambda x: True if x == 'both' else False)
 )

0    False
1     True
2    False
3     True
Name: _merge, dtype: object

这应该比您在函数中的迭代更快;对于不适合内存的数据;我能想到 mmap;但是我自己没有使用过它所以不能给你任何信息。数据表和 dask 可能会有所帮助。

另一种选择是获取数据并转储到sqlite中; 运行 你在那里合并。