根据分数扩展数据

根据分数扩展数据

首先,我有一组 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

相关内容