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

У меня есть ежедневный набор данных временных рядов за 10 лет (1995-2004) с некоторыми пропущенными значениями как 9999,00. Я хотел бы вычислить среднегодовое значение за каждый год без учета пропущенного значения.

Я мог бы сделать это, рассмотрев календарь на 365 дней с помощью следующей команды

awk '!/\9999.00/{sum += $1; count++} NR%365==0{print count ? (sum) :9999.00;sum=count=0}'ifile

Но я не могу изменить календарь високосного года. Мне также нужно добавить еще один столбец с годами. Выход моего желания таков

1995 annual_average
1996 annual_average
1997 annual_average
....

Например: у меня есть следующие данные за 1995-2000 годы. Мне нужно вычислить среднее значение каждых 3 строк вместо 365 и 4 строк вместо 366, если это високосный год:

3
3
4
9999.00
4
9999.00
13
3
9999.00
9999.00
9999.00
9999.00
9999.00
3
4
2
2
2.6
5.1
4.5

Пробная команда:

awk '!/\9999.00/{sum += $1; count++} NR%3==0{print count ? (sum) :9999.00;sum=count=0}'ifile

Выход желания:

1995  3.33
1996  8.5   it is a leap year, so average of 4 lines without considering missing values (4+13)/2
1997  3
1998  9999.00
1999  3
2000  3.55   leap year

person Kay    schedule 27.05.2016    source источник
comment
Что вы подразумеваете под 366-дневным календарем? Вы имеете в виду високосные годы? Вы также должны предоставить пример ввода данных.   -  person xvan    schedule 27.05.2016
comment
Вы можете определить, является ли год високосным, с помощью этого правила и использовать эту информацию для изменения NR%365 на NR%366. Моего awk foo недостаточно, чтобы попытаться это сделать.   -  person xvan    schedule 27.05.2016
comment
Спасибо за дополнительную информацию @xvan Но я не могу изменить свой скрипт. Основная проблема заключается в том, как NR% 365 изменится на NR% 366 за один временной ряд?   -  person Kay    schedule 27.05.2016
comment
Замените NR%365==0 на count ==DY-1, где DY — это переменная, хранящая количество дней в текущем году. Как установить это значение, это то, что вам нужно решить.   -  person xvan    schedule 27.05.2016
comment
По сути, это тот же вопрос, что и stackoverflow.com/questions/37474078/   -  person Michael Vehrs    schedule 27.05.2016


Ответы (1)


Этот код работает для ваших демонстрационных данных. Конечно, вам нужно будет настроить значения target:

BEGIN {
    year = 0;
    target = 3;
}
$1 < 9990.00 {
    sum += $1;
    count++;
}
NR == target {
    if (count == 0) {
        print "9999";
    } else {
        print sum / count;
    }
    sum = 0;
    count = 0;
    year++;
    if (year % 4 == 1) {
        target += 4;
    } else {
        target += 3;
    }
}

О, и имейте в виду, что очень упрощенный расчет високосного года будет неудачным для некоторых лет, хотя и не для тех лет, которые вы упомянули.

person Michael Vehrs    schedule 27.05.2016