如何进行低 RAM 完全交叉连接?
How to do a low RAM full cross join?
希望对点的大型数据文件进行全自交叉连接。但是,我无法使用编程语言来执行操作,因为我无法将其存储在内存中。我想找到集合中所有点的组合。下面是我的数据集的示例。
x y
1 9
2 8
3 7
4 6
5 5
我想交叉连接此数据以生成包含所有点组合的 25 行 table。会有低内存解决方案吗?也许 awk
?
谢谢,
尼古拉斯·海登
P.S。我是一个新手程序员。
也许分两步,创建一个头文件、column1 和 column2 文件并连接 column1 和 column2 并附加到头文件
awk 'NR==1{print > "cross"} NR>1 {print > "col1"; print > "col2"}' file
join -j9 col1 col2 -o1.1,2.1 >> cross
rm col1, col2
显然要确保临时文件名和最终文件名不会与现有文件名冲突。
注意,MacOS 上的 join
命令没有 -j
选项,因此请将其更改为等效的长格式
join -19 -29 col1 col2 -o1.1,2.1 >> cross
在这两种选择中,我们要求 join 使用不存在的第 9 个字段作为键,将第一个文件的每一行与第二个文件的每一行相匹配,以生成两个文件的叉积。
如果内存使用不是问题,我可能会这样做:
$ awk 'NR==1 { print; next } # print the header
{ x[NR]=; y[NR]= } # 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
保持低内存使用率显然需要将数据保持在内存之外,这意味着需要大量访问文件。因此,在为 x
处理 FILENAME
时,使用另一个名称(下面的 file
)打开同一个文件,并按记录为 y
处理该记录:
$ awk 'NR==1 { print; next } # print header
{ file=FILENAME; x=; nr=1 # duplicate FILENAME, keep , create local nr
while((getline <file) > 0) # process file record by record
if(nr++>1) {print x, } # print of FILENAME and of file
close(file) }' file # close the file
x y
1 9
1 8
1 7
1 6
1 5
2 9
...
我可能永远不会使用该代码,因为它可用于任何有用的东西,但也许您可以混合使用这 2 种解决方案来创建合适的东西。
希望对点的大型数据文件进行全自交叉连接。但是,我无法使用编程语言来执行操作,因为我无法将其存储在内存中。我想找到集合中所有点的组合。下面是我的数据集的示例。
x y
1 9
2 8
3 7
4 6
5 5
我想交叉连接此数据以生成包含所有点组合的 25 行 table。会有低内存解决方案吗?也许 awk
?
谢谢,
尼古拉斯·海登
P.S。我是一个新手程序员。
也许分两步,创建一个头文件、column1 和 column2 文件并连接 column1 和 column2 并附加到头文件
awk 'NR==1{print > "cross"} NR>1 {print > "col1"; print > "col2"}' file
join -j9 col1 col2 -o1.1,2.1 >> cross
rm col1, col2
显然要确保临时文件名和最终文件名不会与现有文件名冲突。
注意,MacOS 上的 join
命令没有 -j
选项,因此请将其更改为等效的长格式
join -19 -29 col1 col2 -o1.1,2.1 >> cross
在这两种选择中,我们要求 join 使用不存在的第 9 个字段作为键,将第一个文件的每一行与第二个文件的每一行相匹配,以生成两个文件的叉积。
如果内存使用不是问题,我可能会这样做:
$ awk 'NR==1 { print; next } # print the header
{ x[NR]=; y[NR]= } # 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
保持低内存使用率显然需要将数据保持在内存之外,这意味着需要大量访问文件。因此,在为 x
处理 FILENAME
时,使用另一个名称(下面的 file
)打开同一个文件,并按记录为 y
处理该记录:
$ awk 'NR==1 { print; next } # print header
{ file=FILENAME; x=; nr=1 # duplicate FILENAME, keep , create local nr
while((getline <file) > 0) # process file record by record
if(nr++>1) {print x, } # print of FILENAME and of file
close(file) }' file # close the file
x y
1 9
1 8
1 7
1 6
1 5
2 9
...
我可能永远不会使用该代码,因为它可用于任何有用的东西,但也许您可以混合使用这 2 种解决方案来创建合适的东西。