最初に3列の有効な組み合わせセットがあるため、最終結果はそのファイルのサブセットでなければなりません。
a b c
c b c
p b d
d y d
p y d
x y z
以下のようにスコア行列(スコアファイル)があります。ここで、3番目の列(最大1、最小0)は、2番目の列変数が最初の列変数にどれだけ近いかを示します。
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はaスコア> 0.7なので、変数cとdを含むように拡張できます。
変数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
2つのステップの作業コードがあります
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億4500万のレコードがあり、有効なリストには2600のレコードしかないことです。したがって、これら3つのforループは永遠に実行されます。このプロセスをスピードアップするのに役立ちますか?誤った組み合わせを最初にフィルタリングできると、出力がはるかに小さくなるためです。
これは私がアクセスできるクラスタメモリとOSです。
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
あなたの助けをいただきありがとうございます! !
こんにちはGlenn、サーバーで構文エラーが発生しました。見てください。奇妙なことに、この構文エラーは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をダウンロードしましたが、このエラーは消えました。ご提案いただきありがとうございます。
私はコードをかなり研究しましたが、今では2D配列についてよりよく理解するようになりました。ありがとうございます。
当面の質問について私が正しく理解した場合、根本的な問題があります。つまり、各入力行は他の行とは独立して処理する必要があります。したがって、各入力ラインには可能な出力ラインセットが必要です。
親密さはここから来ています。
各入力行に対して、1) $1 の拡張変数は $1 の 0.7 に近くなければなりません。 2) $2 の拡張変数は $2 の 0.7 に近くなければなりません。 3) $1 配列の各変数に対して、$2 配列の各要素に対して closeless ($1 および $1 配列の変数) + closeless ($2 および $2 配列の変数) は 1.6 より大きくなければなりません。 4)$3を含む拡張変数終値3ドルは0.7でなければなりません。
3つの入力列に基づいて3つの配列を作成すると、「1行あたり」の情報が失われ、圧縮合計が得られません。これが意味があるかどうか教えてください。
可能な調整を試みましたが、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