在 Pandas 中合并两个大型数据框
Posted
技术标签:
【中文标题】在 Pandas 中合并两个大型数据框【英文标题】:Merging two large dataframe in Pandas 【发布时间】:2020-11-10 12:17:35 【问题描述】:当数据量这么大时,我应该如何将数据框df
(800 万行)中的label
列合并到另一个数据框df2
(1.43 亿行)?
基本上我只想将label
列映射到df2
,df
中的所有数据都包含在df2
中,除了label
列。无论如何我可以解决这个问题而不是使用merge()
?
尝试运行下面的代码,但是运行了5个小时没有任何反应。
result = pd.merge(df,df2,on=["X", "Y", "Z"], how='left')
result
df
df2
【问题讨论】:
我认为这是某些数据库的任务,如果需要 python dask 或其他替代方法。在纯熊猫中需要大内存... @jezrael 其实这是点云数据,每一行代表一个数据点。你会推荐使用关系数据库/noSQL 数据库来处理它吗? 不幸的是我没有经验,所以不能:( @jezrael 不用担心,谢谢 :) ! 【参考方案1】:我可以在这里看到一些你可以做的显而易见的事情:
-
假设您只想添加基于
X
/Y
/Z
列和R
/G
/B
的标签是多余的,然后删除R
/@987654328 @/B
df
的列,因为您在最终数据框中不需要它们,当然也不需要它们被复制 1.43 亿次。
根据X
/Y
/Z
的唯一值数量及其数据类型,您可以通过使用如下分类数据类型来减少内存占用:
# Convert to categorical data types (if every value is unique, don't bother!)
for df_temp in [df, df2]:
for col in ['X', 'Y', 'Z']:
df_temp.loc[:, col] = df_temp[col].astype('category')
# Merge using less memory
result = pd.merge(df, df2, on=["X", "Y", "Z"], how='left')
-
最后,您可以尝试对数据进行分区并进行破坏性转换,创建多个数据帧,每个数据帧在非重叠范围内包含
X
,并单独处理它们,然后将各个结果连接起来,为您提供最终结果,例如:
result_dfs = []
ranges = [0, 1000, 2000, 3000, 4000, ...]
for start, end in zip(ranges[:-1], ranges[1:]):
df_idx = (df['X'] >= start) & (df['X'] < end)
df2_idx = (df2['X'] >= start) & (df2['X'] < end)
result_dfs.append(
pd.merge(
df[df_idx],
df2[df2_idx],
on=["X", "Y", "Z"],
how='left'
)
)
# Remove the original data to to reduce memory consumption
df2 = df2[~df2_idx]
result = pd.concat(result_dfs)
这可能仍然行不通,因为在进行最终连接时,您仍然需要在短时间内将完整的数据集两次保存在内存中!
如果这些都不起作用,恐怕你需要更多的内存,或者你需要使用 Pandas 以外的东西来解决你的问题。
【讨论】:
感谢@Chris-Cooper 先生提供详细的解决方案。实际上这是一个点云数据,每一行代表一个数据点。因此,一行的每个 XYZ 都是唯一值,但是我不能删除 RGB 列以保持数据集的完整性。我认为在这种情况下,我不应该指望 Pandas 可以为我完成这项工作。你会建议我应该以数据库/其他方式操作数据吗? 在这种情况下,您最好将其加载到数据库中并使用 SQL 进行连接。以上是关于在 Pandas 中合并两个大型数据框的主要内容,如果未能解决你的问题,请参考以下文章