具有巨大数据框的内部连接(约 200 万列)

Posted

技术标签:

【中文标题】具有巨大数据框的内部连接(约 200 万列)【英文标题】:inner join with huge dataframes (~2 million columns) 【发布时间】:2019-03-14 16:03:31 【问题描述】:

我正在尝试根据在每个数据框中找到的一列(称为“名称”)中的匹配值来连接两个数据框(df1df2)。我已经尝试过使用 R 的 inner_join 函数以及 Python 的 pandas merge 函数,并且已经能够使两者都在我的数据的较小子集上成功工作。我认为我的问题在于我的数据框的大小。

我的数据框如下:

df1 的“名称”列有 5 个附加列,并且有大约 900 行。 df2 的“名称”列有约 200 万列和约 900 行。

我已经尝试过(在 R 中):

df3 <- inner_join(x = df1, y = df2, by = 'Name') 

我也尝试过(在 Python 中,df1df2 是 Pandas 数据框):

df3 = df1.merge(right = df2, how = 'inner', left_on = 1, right_on = 0)   

(其中“名称”列位于 df1 的索引 1 和 df2 的索引 0)

当我将上述内容应用于我的完整数据帧时,它会运行很长时间并最终崩溃。此外,我怀疑问题可能出在我的df2 的 200 万列上,所以我尝试将它(按行)子设置为更小的数据帧。我的计划是将df2 的小子集与df1 结合起来,然后在最后将新的数据帧绑定在一起。然而,即使是更小的分区df2s 也不能成功。

如果有人能提供任何建议,我将不胜感激。

【问题讨论】:

您能谈谈各个对象的内存占用量(以 MB/GB 为单位)以及您可用的操作系统/内存量吗? 尝试使用data.table 你的列应该是行吗?重塑为长格式可能会简化事情。 如果内存问题是一个问题,并且您想使用 python,您可以尝试使用 dask 数据框。 docs.dask.org/en/latest/dataframe.html - 这是 1:1、1:many many:1 还是 many:many 合并? 【参考方案1】:

感谢大家的帮助!按照@shadowtalker 的建议使用 data.table,极大地加快了进程。仅供参考,以防万一有人尝试做类似的事情,df1 大约为 400 mb,而我的 df2 文件大约为 3gb。

我能够完成以下任务:

library(data.table)
df1 <- setDT(df1)
df2 <- setDT(df2)
setkey(df1, Name)
setkey(df2, Name)
df3 <- df1[df2, nomatch = 0]

【讨论】:

【参考方案2】:

这是一个非常丑陋的解决方法,我分解了 df2 的列并逐个添加它们。不确定它是否会起作用,但可能值得一试:

# First, I only grab the "Name" column from df2
df3 = df1.merge(right=df2[["Name"]], how="inner", on="Name")  

# Then I save all the column headers (excluding 
# the "Name" column) in a separate list
df2_columns = df2.columns[np.logical_not(df2.columns.isin(["Name"]))]

# This determines how many columns are going to get added each time.
num_cols_per_loop = 1000

# And this just calculates how many times you'll need to go through the loop
# given the number of columns you set to get added each loop
num_loops = int(len(df2_columns)/num_cols_per_loop) + 1

for i in range(num_loops):
    # For each run of the loop, we determine which rows will get added
    this_column_sublist = df2_columns[i*num_cols_per_loop : (i+1)*num_cols_per_loop]

    # You also need to add the "Name" column to make sure 
    # you get the observations in the right order
    this_column_sublist = np.append("Name",this_column_sublist)

    # Finally, merge with just the subset of df2
    df3 = df3.merge(right=df2[this_column_sublist], how="inner", on="Name")

就像我说的,这是一个丑陋的解决方法,但它可能会奏效。

【讨论】:

以上是关于具有巨大数据框的内部连接(约 200 万列)的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记大数据原理与技术 —— HBase大数据数据库

oracle数据库约200W数据查询非常慢,查询需要10几秒,经常查询超时,这个正常吗?有没有啥好的办法解决

使用 bash 脚本在数百万列中子集列

具有大数据框的独立组的多重 t 检验

优化巨大的 JSON 响应

大数据原理与技术:分布式数据库HBase