Использование awk для интерполяции столбца данных на основе файла данных с датой и временем
В следующем файле есть несколько столбцов с датой, временем и неполным набором данных, как показано с использованием простого файла
# Matrix.txt
13.09.2016:23:44:10;;4.0
13.09.2016:23:44:20;10.0;
13.09.2016:23:44:30;;
13.09.2016:23:44:40;30.0;7.0
Как я могу сделать линейную интерполяцию для каждого столбца, используя awk, чтобы получить недостающие данные:
# Output.txt
13.09.2016:23:44:10;0.0;4.0
13.09.2016:23:44:20;10.0;5.0
13.09.2016:23:44:30;20.0;6.0
13.09.2016:23:44:40;30.0;7.0
1 ответ
Вот одно решение в Gnu awk. Он запускается дважды для первого заданного файла данных, запоминает первую и последнюю точки данных (y1, y2) и их временные метки (x2, x2), вычисляет наклоны точек (k = (y2-y1) / (x2-x1)) и интерполирует и экстраполирует значения для пустых элементов ((y = (x1-x) + y1).
Это не доказательство, оно не проверяет деление на нули или наличие двух точек для уклонов или каких-либо других проверок вообще.
$ cat inexpolator.awk
BEGIN {
FS=OFS=";"
ARGC=3; ARGV[2]=ARGV[1] # run it twice for first file
}
BEGINFILE { # on the second round
for(i in p) # compute the slopes
k[i]=(y2[i]-y1[i])/(x2[i]-x1[i])
}
{
split($1,a,"[:.]") # reformat the timestamp
ts=mktime(a[3] " " a[2] " " a[1] " " a[4] " " a[5] " " a[6])
}
NR==FNR { # remember first and last points for slopes
for(i=2;i<=NF;i++) {
p[i]
if(y1[i]=="") { y1[i]=$i; x1[i]=ts }
if($i!="") { y2[i]=$i; x2[i]=ts }
}
next # only on the first round
}
{ # reformat ts again for output
printf "%s", strftime("%d.%m.%Y:%H:%M:%S",ts) OFS # print ts
for(i=2;i<=NF;i++) {
if($i=="") $i=k[i]*(ts-x1[i])+y1[i] # compute missing points
printf "%.1f%s", $i, (i<NF?OFS:ORS) # print points
}
}
Запустить его:
$ awk -f inexpolator.awk Matrix.txt
13.09.2016:23:44:10;0.0;4.0
13.09.2016:23:44:20;10.0;5.0
13.09.2016:23:44:30;20.0;6.0
13.09.2016:23:44:40;30.0;7.0