使用 AWK 的最小-最大规范化
Min-Max Normalization using AWK
我不知道为什么我无法遍历所有记录。目前它用于最后一条记录并为其打印规范化。
归一化公式:
New_Value = (值 - min[i]) / (max[i] - min[i])
计划
{
for(i = 1; i <= NF; i++)
{
if (min[i]==""){ min[i]=$i;} #initialise min
if (max[i]==""){ max[i]=$i;} #initialise max
if ($i<min[i]) { min[i]=$i;} #new min
if ($i>max[i]) { max[i]=$i;} #new max
}
}
END {
for(j = 1; j <= NF; j++)
{
normalized_value[j] = ($j - min[j])/(max[j] - min[j]);
print $j, normalized_value[j];
}
}
数据集
4 14 24 34
3 13 23 33
1 11 21 31
2 12 22 32
5 15 25 35
当前输出
5 1
15 1
25 1
35 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
我会处理文件两次,一次确定minima/maxima,一次计算标准化值:
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 脚本保存为 norm.awk
。您可以 运行 来自 shell 的这个(并在需要时重定向)为:
awk -f norm.awk data.txt > norm_output.txt
或者您可以 运行 来自 vim 本身的这个 norm.awk
脚本作为:
:%!awk -f norm.awk
这将用最小-最大规范化值替换现有值。
我不知道为什么我无法遍历所有记录。目前它用于最后一条记录并为其打印规范化。
归一化公式:
New_Value = (值 - min[i]) / (max[i] - min[i])
计划
{
for(i = 1; i <= NF; i++)
{
if (min[i]==""){ min[i]=$i;} #initialise min
if (max[i]==""){ max[i]=$i;} #initialise max
if ($i<min[i]) { min[i]=$i;} #new min
if ($i>max[i]) { max[i]=$i;} #new max
}
}
END {
for(j = 1; j <= NF; j++)
{
normalized_value[j] = ($j - min[j])/(max[j] - min[j]);
print $j, normalized_value[j];
}
}
数据集
4 14 24 34
3 13 23 33
1 11 21 31
2 12 22 32
5 15 25 35
当前输出
5 1
15 1
25 1
35 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
我会处理文件两次,一次确定minima/maxima,一次计算标准化值:
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 脚本保存为 norm.awk
。您可以 运行 来自 shell 的这个(并在需要时重定向)为:
awk -f norm.awk data.txt > norm_output.txt
或者您可以 运行 来自 vim 本身的这个 norm.awk
脚本作为:
:%!awk -f norm.awk
这将用最小-最大规范化值替换现有值。