Primeiramente eu tenho um conjunto de combinações válidas de 3 colunas (validlist), então o resultado final deve ser um subconjunto deste arquivo.
a b c
c b c
p b d
d y d
p y d
x y z
Eu tenho uma matriz de pontuação como abaixo (scorefile), onde a 3ª coluna (1 max, 0 min) diz o quão perto a variável da 2ª coluna é para a variável da 1ª coluna
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
Dado um conjunto de variáveis, eu preciso expandir a seleção para outras combinações que são significativamente próximas (> 0.7) para as variáveis de coluna dadas também a soma de proximidade é maior que 1.6. .
Por exemplo: a variável a pode ser expandida para incluir as variáveis c e d, pois elas têm pontuações > 0,7 com um.
A variável b, pode ser expandida para incluir y, e c pode incluir m e n.
Então, minha entrada de exemplo é
a b c
d b a
e saída expandida é
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
que é então subconjunto pela lista de validação para ter o resultado final.
a b c
c b c
p b d
d y d
p y d
Eu tenho um código de trabalho para as duas etapas
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
O problema é que o arquivo de pontuação tem 345 milhões de registros e a lista válida tem apenas 2600 registros. Então, os 3 loops for duram para sempre, você pode ajudar a acelerar o processo, porque se pudermos filtrar as combinações inválidas primeiro, a saída será muito menor.
Aqui está a memória do cluster e os que eu tenho acesso a
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
Muito obrigado pela sua ajuda !!
Oi Glenn, estou recebendo um erro de sintaxe no servidor. Por favor, dê uma olhada? Estranhamente, esse erro de sintaxe não aparece no 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
#
Atualização:
Oi Glenn,
Eu baixei o gawk 4.xxx e esse erro acabou. Obrigado pela sugestão.
Brinquei bastante com o código e acho que entendo melhor as matrizes bidimensionais agora, obrigado.
Quanto ao problema em questão, se eu entendi corretamente, há um possível problema de que cada linha de entrada deve ser processada independentemente das outras. Portanto, deve haver um conjunto de possíveis linhas de saída para cada linha de entrada.
É aí que entra a soma de proximidade,
Para cada linha de entrada
1) Variáveis expandidas com $ 1 devem ser 0.7 fechadas com $ 1.
2) Variáveis expandidas com $ 2 devem ser 0.7 fechadas com $ 2.
3) Para cada variável na matriz $ 1, para cada elemento na matriz $ 2
Sem closeless ($ 1 com variável em $ 1 array) + sem clos ($ 2 com variável em $ 2 array) deve ser maior que 1,6
4) Variáveis expandidas com $ 3 devem ser 0.7 fechadas com $ 3.
À medida que você cria três matrizes com base nas três colunas de entrada, as informações "para cada linha" estão sendo perdidas e a soma de proximidade não pode ser implementada. Por favor, deixe-me saber se isso faz sentido.
Eu tentei um possível ajuste, mas acho que estou perdido na complexidade dos arrays 2-dim e também na possibilidade de usar um array 3-dim. Por favor, ajude
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