首先,我有一组 3 列的有效组合(validlist),因此最终结果必须是该文件的子集。
a b c
c b c
p b d
d y d
p y d
x y z
我有一个如下所示的分数矩阵(scorefile),其中第三列(最大 1,最小 0)表示第二列变量与第一列变量的接近程度
a b 0.3
a c 0.87
a d 0.75
b x 0.87
b y 0.98
b z 0.24
c m 0.9
c n 0.86
d p 0.87
给定一组变量,我需要将选择扩展到与给定列变量显着接近 (> 0.7) 的其他组合,并且接近度总和大于 1.6。 。
例如:变量 a 可以扩展为包含变量 c 和 d,因为它们的 a 得分 > 0.7。
变量 b 可以扩展为包含 y,而 c 可以包含 m 和 n。
所以我的示例输入是
a b c
d b a
扩展输出为
intermediate output
a b c
c b c
d b c
a y c
c y c
d y c
a b m
c b m
d b m
a y m
c y m
d y m
a b n
c b n
d b n
a y n
c y n
d y n
d b a
p b a
d y a
p y a
d b c
p b c
d y c
p y c
d b d
p b d
d y d
p y d
然后将其作为有效列表的子集以获得最终输出。
a b c
c b c
p b d
d y d
p y d
我有两个步骤的工作代码
awk '
NR==FNR {
if ($3 > 0.7) {
scr[$1,$2]=$3
var[$1]
}
next
}
{
for (col1 in var) {
for (col2 in var) {
for (col3 in var) {
if (
scr[$1,col1] && scr[$2,col2] && scr[$3,col3] &&
scr[$1,col1] > 0.7 &&
scr[$2,col2] > 0.7 &&
scr[$3,col3] > 0.7 &&
scr[$1,col1] + scr[$1,col1] > 1.6
) {
print col1, col2, col3
}
}
}
}
}
' score input > intermediateout
grep -f intermediateout validlist > finalout
问题是分数文件有 3.45 亿条记录,而有效列表只有 2600 条记录。所以这3个for循环永远运行,你能帮助加快这个过程吗?因为如果我们能先过滤掉无效的组合,输出就会小得多。
这是我可以访问的集群内存和操作系统
free -m
total used free shared buffers cached
Mem: 387591 299120 88471 2 481 292698
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.6
非常感谢你的帮助 !!
嗨格伦,我在服务器上收到语法错误。请您看一下好吗?奇怪的是,这个语法错误在 cygwin 上没有显示。
awk: cmd. line:9: if ($3 > 0.7) clos[$1][$2] # I would name this array "close"
awk: cmd. line:9: ^ syntax error
awk: cmd. line:15: col[i][$i]
awk: cmd. line:15: ^ syntax error
awk: cmd. line:16: for (key in clos[$i])
awk: cmd. line:16: ^ syntax error
awk: cmd. line:17: col[i][key]
awk: cmd. line:17: ^ syntax error
awk: cmd. line:24: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:24: ^ syntax error
awk: cmd. line:24: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:24: ^ syntax error
awk: cmd. line:24: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:24: ^ syntax error
awk: cmd. line:24: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:24: ^ syntax error
awk: cmd. line:24: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:24: ^ syntax error
awk: cmd. line:24: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:24: ^ syntax error
awk: cmd. line:25: if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
awk: cmd. line:25: ^ unexpected newline or end of string
#
更新:
嗨格伦,
我下载了 gawk 4.xxx,这个错误就消失了。感谢您的建议。
我对代码进行了相当多的研究,我想我现在对二维数组有了更好的理解,谢谢。
至于手头的问题,如果我理解正确,则存在一个潜在的问题:每个输入行必须独立于其他行进行处理。因此每个输入行应该有一组可能的输出行。
这就是亲密感的来源,
对于每个输入行 1) 具有 $1 的扩展变量必须与 $1 接近 0.7。 2) 带有$2 的扩展变量必须与$2 接近0.7。 3) 对于 $1 数组中的每个变量,对于 $2 数组中的每个元素 closeless($1 与 $1 数组中的变量)+ closeless($2 与 $2 数组中的变量)必须大于 1.6 4) 与 $3 的扩展变量必须是 0.7收盘价为 3 美元。
当您基于 3 个输入列创建 3 个数组时,“每行”信息将会丢失,并且无法实现紧密度总和。请告诉我这是否有意义。
我尝试了可能的调整,但我认为我迷失在 2 维数组的复杂性以及使用 3 维数组的可能性中。
gawk '
# validlist
FILENAME == ARGV[1] {
valid[$1 FS $2 FS $3]
next
}
# scorefile
FILENAME == ARGV[2] {
if ($3 > 0.7) clos[$1][$2]
scr[$1][$2]=$3; # I would name this array "close"
next # but that is a keyword
}
# input
{
col[NR FS $2][$1];
col[NR FS $2][$2];
col[NR FS $3][$3];
for (key in clos[$i])
{
col[NR FS $1][$i];
col[NR FS $2][$i];
col[NR FS $3][$i];
if scr[$1][i] + scr[$2][i] > 1.6
possible[$i]=$1 FS $2 FS $3
}
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (v in valid) {
for (allposs in possible)
if ( v==allpos )
print v
}
}
' validlist scorefile input
答案1
好的,给你。关键是让 awk 程序也读取有效列表。处理乐谱和输入文件。然后循环有效的组合,而不是所有的排列。
对数组的数组使用 GNU awk
gawk '
# validlist
FILENAME == ARGV[1] {
valid[$1 FS $2 FS $3]
next
}
# scorefile
FILENAME == ARGV[2] {
if ($3 > 0.7) clos[$1][$2] # I would name this array "close"
next # but that is a keyword
}
# input
{
for (i=1; i<=3; i++) {
col[i][$i]
for (key in clos[$i])
col[i][key]
}
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (v in valid) {
split(v, a)
if ( (a[1] in col[1]) && (a[2] in col[2]) && (a[3] in col[3]) )
print v
}
}
' validlist scorefile input
输出
a b c
c b c
d y d
p b d
p y d