คำนวณค่าเฉลี่ยรายปีจากอนุกรมเวลาในปฏิทินปีอธิกสุรทินโดยใช้เชลล์สคริปต์

ฉันมีชุดข้อมูลอนุกรมเวลารายวันเป็นเวลา 10 ปี (พ.ศ. 2538-2547) โดยมีค่าที่ขาดหายไปบางส่วนเป็น 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