Bash 使用AWK的最小-最大归一化
我不知道为什么我不能循环浏览所有的记录。目前,它用于最后一条记录并打印其规范化 标准化公式: 新的_值=(值-min[i])/(最大值[i]-min[i]) 节目 电流输出 所需输出Bash 使用AWK的最小-最大归一化,bash,shell,awk,text-processing,gawk,Bash,Shell,Awk,Text Processing,Gawk,我不知道为什么我不能循环浏览所有的记录。目前,它用于最后一条记录并打印其规范化 标准化公式: 新的_值=(值-min[i])/(最大值[i]-min[i]) 节目 电流输出 所需输出 我将处理文件两次,一次确定最小值/最大值,一次计算归一化值: awk ' NR==1 { for (i=1; i<=NF; i++) { min[i]=$i max[i]=$i } next }
我将处理文件两次,一次确定最小值/最大值,一次计算归一化值:
awk '
NR==1 {
for (i=1; i<=NF; i++) {
min[i]=$i
max[i]=$i
}
next
}
NR==FNR {
for (i=1; i<=NF; i++) {
if ($i < min[i]) {min[i]=$i}
else if ($i > max[i]) {max[i]=$i}
}
next
}
{
for (i=1; i<=NF; i++) printf "%.2f%s", ($i-min[i])/(max[i]-min[i]), FS
print ""
}
' file file
# ^^^^ ^^^^ same file twice!
给定的答案使用相同的文件加载两次,这可以通过以下修改的脚本避免:
# initialization on min, max and value array to be used later
NR == 1 {
for (i=1; i<=NF; i++) {
value[i] = $i
min[i] = $i
max[i] = $i
}
}
# finding min and max for each column
NR > 1 {
for (i=1; i<=NF; i++) {
value[((NR-1)*NF)+i] = $i
if ($i < min[i]) {min[i] = $i}
else if ($i > max[i]) {max[i] = $i}
}
}
END {
nrows = NF
ncolumns = NR
for (i=0; i<(ncolumns); i++ ) {
for (j=1; j<(nrows); j++ ) {
printf "%.2f%s", (value[(i*nrows)+j]-min[j])/(max[j]-min[j]), OFS
}
printf "%.2f\n", (value[(i*nrows)+j]-min[j])/(max[j]-min[j])
}
}
或者您可以从vim本身运行这个norm.awk
脚本,如下所示:
:%!awk -f norm.awk
它将用最小-最大规范化值替换现有值。
结束
块中的$j
将是数据集中最后一条记录的第j
字段的值。首先,我不理解您需要的输出。这些数字来自哪里?什么的名字?马克斯什么?第二,你在你的END子句中引用了NF,这真的没有意义。我对awk是个新手,很难理解awk语言,对此表示抱歉。最小值和最大值是从我展示的数据集计算出来的,我计算了每个字段(列)的最小值和最大值,然后最后使用最小值-最大值算法对每个字段进行规格化。最小值[i]从不==“”在你询问的时候,它默认为0,我终于明白了。你能看看我的另一个问题吗。在awk上。这很有用。我的输入数据包含标题和带有ID的第一列。如何使用此脚本将此信息包含在输出中?假设头是第一行,将FNR==1{next}
添加为awk代码的第一行。对于第一列,考虑如何调整for循环。我使用建议的脚本来规范化我的数据,但是我得到了这个错误消息:AWK:CMD。第17行:(FILENAME=input.txt FNR=1)致命:尝试除以零。如何解决?
0.75 0.75 0.75 0.75
0.50 0.50 0.50 0.50
0.00 0.00 0.00 0.00
0.25 0.25 0.25 0.25
1.00 1.00 1.00 1.00
awk '
NR==1 {
for (i=1; i<=NF; i++) {
min[i]=$i
max[i]=$i
}
next
}
NR==FNR {
for (i=1; i<=NF; i++) {
if ($i < min[i]) {min[i]=$i}
else if ($i > max[i]) {max[i]=$i}
}
next
}
{
for (i=1; i<=NF; i++) printf "%.2f%s", ($i-min[i])/(max[i]-min[i]), FS
print ""
}
' file file
# ^^^^ ^^^^ same file twice!
0.75 0.75 0.75 0.75
0.50 0.50 0.50 0.50
0.00 0.00 0.00 0.00
0.25 0.25 0.25 0.25
1.00 1.00 1.00 1.00
# initialization on min, max and value array to be used later
NR == 1 {
for (i=1; i<=NF; i++) {
value[i] = $i
min[i] = $i
max[i] = $i
}
}
# finding min and max for each column
NR > 1 {
for (i=1; i<=NF; i++) {
value[((NR-1)*NF)+i] = $i
if ($i < min[i]) {min[i] = $i}
else if ($i > max[i]) {max[i] = $i}
}
}
END {
nrows = NF
ncolumns = NR
for (i=0; i<(ncolumns); i++ ) {
for (j=1; j<(nrows); j++ ) {
printf "%.2f%s", (value[(i*nrows)+j]-min[j])/(max[j]-min[j]), OFS
}
printf "%.2f\n", (value[(i*nrows)+j]-min[j])/(max[j]-min[j])
}
}
awk -f norm.awk data.txt > norm_output.txt
:%!awk -f norm.awk