Скользящая средняя и разница - PullRequest
0 голосов
/ 26 сентября 2018

Я хотел бы рассчитать скользящее / скользящее среднее для столбца 2 ($ 2) в моем файле данных (data.txt), используя окно из 5 (более пяти последовательных строк), а затем разницу между первым и последним значением в пределахкаждое окно с использованием AWK.Пожалуйста, ознакомьтесь с моими данными ниже:

> cat data.txt
2001         100
2002         110
2003         120
2004         130
2005         140
2006         900
2007         910
2008         920
2009         930
2010         940

> awk 'BEGIN{size=5} {mod=NR%size; if(NR<=size){count++}else{sum-=array[mod]};sum+=$2;array[mod]=$2;print $1"\t", $2"\t", sum/count}' data.txt
2001     100     100
2002     110     105
2003     120     110
2004     130     115
2005     140     120
2006     900     280
2007     910     440
2008     920     600
2009     930     760
2010     940     920

Как видно из приведенного выше выходного документа, я могу сделать скользящее среднее на 2 доллара (на выходе в 3 доллара), используя скрипт AWK, показанный выше.Но как я могу изменить свой сценарий AWK выше, чтобы я также мог распечатать разницу в 4 доллара между первым и последним значением 2 доллара для каждого окна?Например, я хотел бы, чтобы вышеприведенный вывод выглядел так:

2001     100     100     
2002     110     105
2003     120     110
2004     130     115
2005     140     120      120-100
2006     900     280      280-105
2007     910     440      440-110
2008     920     600      600-115
2009     930     760      760-120
2010     940     920      920-280

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Вам также необходимо запомнить последние значения третьего столбца:

awk 'BEGIN{size=5}
{
  mod=NR%size; 
  if(NR<=size) {
    count++
  } else {
    sum-=array[mod]
  };
  sum+=$2;
  avg=sum/count;
  if (NR>=size) {
    diff=avg"-"array2[(mod+1)%size]; # remove quotes to display result as a number
  }
  array[mod]=$2;
  array2[mod]=avg;

  print $1"\t", $2"\t", avg, diff
}
' data.txt

РЕДАКТИРОВАТЬ: ваше текущее описание не соответствует примеру в вопросе (4 доллара должны отличаться от 2 или 3 долларов)?,Мой ответ решает ваш пример и Barmars ваше описание:)

0 голосов
/ 26 сентября 2018

Если вы не привязаны к awk, Perl довольно аккуратен.Предполагается, что для столбца 4 вы подразумеваете разницу между первым и последним средним окном.

perl -MList::Util=sum0 -slane '
    unshift @values, $F[1];            # add current value to window of values
    splice @values, $size;             # trim window to desired size
    $avg = sum0(@values) / scalar(@values);

    unshift @averages, $avg;
    splice @averages, $size;

    push @F, $avg;
    # remove quotes below if you want the actual difference
    push @F, "$averages[0]-$averages[-1]" if scalar(@values) == $size;
    print join "\t", @F
' -- -size=5 data.txt
2001    100     100
2002    110     105
2003    120     110
2004    130     115
2005    140     120     120-100
2006    900     280     280-105
2007    910     440     440-110
2008    920     600     600-115
2009    930     760     760-120
2010    940     920     920-280
0 голосов
/ 26 сентября 2018

Прежде чем заменить array[mod], сохраните разницу другой переменной, чтобы вы могли напечатать ее в новом столбце.

awk 'BEGIN{size=5} 
    {   mod=NR%size; 
        if(NR<=size){count++;}
        else{sum-=array[mod]};
        sum+=$2;
        if (NR >= size) {diff = $2"-"array[mod]}
        array[mod]=$2;
        print $1"\t", $2"\t", sum/count"\t", diff
    }' data.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...