如何做低RAM全交叉连接?

时间:2017-04-15 03:56:50

标签: mysql unix memory awk cross-product

我希望在点的大数据文件上执行完全自交联接。但是,我不能使用编程语言来执行操作,因为我无法将其存储在内存中。我想找到集合中所有点的组合。下面是我的数据集的一个例子。

x y 
1 9 
2 8 
3 7 
4 6 
5 5 

我想交叉加入这些数据,以生成包含所有点组合的25行表。是否会有低内存解决方案?也许是awk

谢谢,

尼古拉斯·海登

P.S。我是新手程序员。

2 个答案:

答案 0 :(得分:1)

或许分两步,创建一个header,column1和column2文件并加入column1和column2并附加到头文件

awk 'NR==1{print > "cross"} NR>1 {print $1 > "col1"; print $2 > "col2"}' file
join -j9 col1 col2 -o1.1,2.1 >> cross
rm col1, col2

显然要确保temp和final文件名不会与现有文件名冲突。

请注意,MacOS上的join命令没有-j选项,因此请将其更改为等效的长格式

join -19 -29 col1 col2 -o1.1,2.1 >> cross

在两个备选方案中,我们要求join使用不存在的第9个字段作为键,它将第一个文件的每一行与第二个文件中的每一行匹配,以生成两个文件的叉积。

答案 1 :(得分:1)

如果内存使用不是问题,我可能会这样做:

$ awk 'NR==1 { print; next }          # print the header
      { x[NR]=$1; y[NR]=$2 }          # read data ro two hashes x and y
      END { for(i=2;i<=NR;i++)
                for(j=2;j<=NR;j++)
                    print x[i],y[j]   # print all combinations of x and y
      }' file

显着降低内存使用率需要将数据保留在内存之外,这意味着要大量访问文件。因此,在为FILENAME处理x时,请使用其他名称(下面为file)打开同一文件,然后按y的记录处理该记录:

$ awk 'NR==1 { print; next }          # print header
      { file=FILENAME; x=$1; nr=1     # duplicate FILENAME, keep $1, create local nr
        while((getline <file) > 0)    # process file record by record
            if(nr++>1) {print x,$2 }  # print $1 of FILENAME and $2 of file
        close(file) }' file           # close the file
x y 
1 9
1 8
1 7
1 6
1 5
2 9
...

我可能永远不会使用那些代码,因为它可以用于任何有用的东西,但也许你可以将这两种解决方案混合起来以创造合适的东西。