目前我正在学习Perl和gnuplot。我想知道如何根据下一个值计算某个值。例如,我有一个文本文件包含:
#ID(X) Y
1 1
3 9
5 11
输出也应显示未知ID的值。因此,输出应显示:
#ID(X) Y
1 1
2 5
3 9
4 10
5 11
ID#2的Y基于以下内容: ((2-3)/(1-3))* 1 +((2-1)/(3-1))* 9是线性代数
Y2=((X2-X3)/(X1-X3))*Y1 + ((X2-X1)/(X3-X1)) * Y3
同样适用于ID#5
目前我有这段代码,
#! /usr/bin/perl -w
use strict;
my $prev_id = 0;
my $prev_val = 0;
my $next_id;
my $next_val;
while (<>)
{
my ($id, $val) = split;
for (my $i = $prev_id + 1; $i < $next_id; $i++)
{
$val = (($id - $next_id) / ($prev_id - $next_id)) * $prev_val + (($id - $prev_id) / ($next_id - $prev_id)) * $next_val;
printf ("%d %s\n", $i, $val);
}
printf ("%d %s\n", $id, $val);
($prev_val, $prev_id) = ($val, $id);
($next_val, $next_id) = ($prev_val, $prev_id);
}
答案 0 :(得分:1)
你的公式似乎比我预期的要复杂,因为你总是处理1的整数间距。
您没有说是否要为多个连续缺失值填补空白,但我们假设您要这样做。
你所做的就是在第一行读到,并说这是当前的一行并输出它。现在你读了下一行,如果它的ID不是预期的那个,你用简单的线性插值来填补空白......
伪代码
(currID, currY) = readline()
outputvals( currID, currY )
while lines remain do
(nextID, nextY) = readline()
gap = nextID - currID
for i = 1 to gap
id = currID + i
y = currY + (nextY - currY) * i / gap
outputvals( id, y )
end
(currID, currY) = (nextID, nextY)
end
抱歉非Perl代码。这只是我多年没有使用Perl,并且不记得一半的语法。 =)这里的概念很容易翻译成代码。
答案 1 :(得分:0)
您表示您的问题是获得下一个值。关键是不要向前看,而应该向后看。
my $prev = get first value;
my ($prev_a, $prev_b) = parse($prev);
my $this = get second value;
my ($this_a, $this_b) = parse($this);
while ($next = get next value) {
my ($next_a, $next_b) = parse($next);
...
$prev = $this; $prev_a = $this_a; $prev_b = $this_b;
$this = $next; $this_a = $next_a; $this_b = $next_b;
}
答案 2 :(得分:0)
使用数组可能是最佳选择。这也将使您的数据可供进一步操作。
**警告:对于y的多个连续缺失值不起作用;看@ paddy的答案。
#!/usr/bin/perl
use strict;
use warnings;
my @coordinates;
while (<DATA>) {
my ($x, $y) = split;
$coordinates[$x] = $y;
}
# note that the for loop starts on index 1 here ...
for my $x (1 .. $#coordinates) {
if (! $coordinates[$x]) {
$coordinates[$x] = (($x - ($x + 1)) / (($x - 1) - ($x + 1)))
* $coordinates[$x - 1]
+ (($x - ($x - 1)) / (($x + 1) - ($x - 1)))
* $coordinates[$x + 1];
}
print "$x - $coordinates[$x]\n";
}
__DATA__
1 1
3 9
5 11
答案 3 :(得分:-1)
#! /usr/bin/perl -w
use strict;
my @in = (1,9,11);
my @out;
for (my $i = 0; $i<$#in; $i++) {
my $j = $i*2;
my $X1 = $i;
my $X2 = $i+1;
my $X3 = $i+2;
my $Y1 = $in[$i];
my $Y3 = $in[$i+1];
my $Y2 = $Y1*(($X2-$X3)/($X1-$X3))
+ $Y3*(($X2-$X1)/($X3-$X1));
$out[$j] = $in[$i];
$out[$j+1] = $Y2;
}
$out[$#in*2] = $in[$#in];
print (join " ",@out);