damyarou

python, GMT などのプログラム

Python 月次及び年次データ集計(流量)

概要

日平均流量の月次および年次データ集計のプログラム。

ここでは流量の集計を行い、月平均・年平均を算出している。 年平均は、「月平均の平均」ではなく、「1年間全データの平均」としている。 これは365日の流況図から出した年平均と数値を合わせるため。 「月平均の平均」と「年間全データの平均」は結構違う場合があるので注意。

計算のルール

入力

データ取得開始日の月初めから、データ取得完了日の月末まで、データの有無に関わらず、全ての日付が連続的に入力されていること。

出力

  • 各月の中で1日でも欠測があれば、その月の平均は nan とする
  • 各年の平均は、各年の全データ(365日あるいは366日)の平均とする。その年に1日でも欠測があればその年の平均は nan とする。
  • 各月の集計平均(最終行)は、欠測を含まない月の全データの平均値とする。欠測がある月のデータは月平均の計算に用いない。

出力例

  • 年別に各月の平均日流量を表示している。
  • 最終列はその年の平均日流量。
  • 最終行は各月の年をまたいだ平均日流量。
  • Wordに貼り付けて数表を作るため、画面にCSVイメージで出力する。
  • 各月の中で、1日でも欠測があれば月平均は、nanとしている。
  • nan の月を含む年の平均はもちろん nan である。
Year,   Jan,   Feb,   Mar,   Apr,   May,   Jun,   Jul,   Aig,   Sep,   Oct,   Nov,   Dec,  Ave.
2013,  70.6,  83.3, 118.3, 124.3, 117.4, 115.6,  93.4,  53.2,  41.1,  28.4,  76.7, 113.9,  86.3
2014,  46.9,  36.5,  59.2,  71.9,  42.1,  86.1,  79.0,  50.6,  28.1,   nan,  23.0,   nan,   nan
2015,  47.5,  95.7, 101.0,  90.9,  74.9,  37.8,  32.0,  27.8,  15.4,  14.0,   9.1,  37.0,  48.3
2016,  38.2,  72.3, 125.8, 145.9,  72.2,  80.1,  49.4,  54.0,  49.7,  92.2, 112.1,  54.1,  78.7
2017,  50.7,  63.0,  99.2, 108.1, 128.7, 105.6,  86.3,   nan,   nan,   nan,   nan,   nan,   nan
2018,   nan,   nan,   nan,   nan,  84.1,   nan,   nan,   nan,  31.9,  32.6,  37.4,  64.7,   nan
2019,  55.2,  91.4,  68.4, 105.9,  88.5,   nan,   nan,   nan,   nan,   nan,   nan,   nan,   nan
Ave.,  51.5,  73.7,  95.3, 107.8,  86.8,  85.0,  68.0,  46.4,  33.2,  41.8,  51.7,  67.4,  71.1

プログラム

#====================================
# Data aggregation (monthly & yearly)
#====================================
import pandas as pd
import numpy as np
import datetime


def rdata():
    fnameR='df_qq2.csv' # input file name
    df=pd.read_csv(fnameR, header=0, index_col=0) # read excel data
    df.index = pd.to_datetime(df.index, format='%Y/%m/%d')
    return df    
    

def cal_m(rf,lyyy,lmmm):
    qqm=np.zeros((len(lyyy)+1,len(lmmm)+1),dtype=np.float64)
    kda=np.zeros((len(lyyy)+1,len(lmmm)+1),dtype=np.float64)
    for i,yy in enumerate(lyyy):
        for j,mm in enumerate(lmmm):
            ss=yy+'/'+mm
            try:
                qqm[i,j]=rf[ss].sum() # sum in a month
                kda[i,j]=rf[ss].count() # availavle days
                nac=np.count_nonzero(np.isnan(rf[ss])) # unavailable days
            except KeyError:
                qqm[i,j]=np.nan
                kda[i,j]=np.nan
            if 0<nac:
                qqm[i,j]=np.nan
                kda[i,j]=np.nan
        qqm[i,-1]=np.sum(qqm[i,:]) # sum in a year
        kda[i,-1]=np.sum(kda[i,:]) # sum in a year of available days
    for j in range(len(lmmm)+1):
        qqm[-1,j]=np.nansum(qqm[:,j])
        kda[-1,j]=np.nansum(kda[:,j])
    qmean=qqm/kda
    return qmean


def qq_mon(lyy,lmm,qq):
    qqm=cal_m(qq,lyy,lmm)
    ss='{0:4s}'.format('Year')
    for m in ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aig','Sep','Oct','Nov','Dec','Ave.']:
        ss=ss+',{0:>6s}'.format(m)
    print(ss)
    lyy=lyy+['Ave.']
    for i,yy in enumerate(lyy):
        ss='{0:4s}'.format(yy)
        for j in range(len(lmm)+1):
            ss=ss+',{0:6.1f}'.format(qqm[i,j])
        print(ss)               


def main():
    df0=rdata() # daily rainfall at each area (2000.03-2019.06)
    lyy=['2013','2014','2015','2016','2017','2018','2019']
    lmm=['01','02','03','04','05','06','07','08','09','10','11','12']

    print('* Monthly discharge at Teromu GS')
    qq=pd.Series(df0['q_tot'], index=df0.index)
    qq_mon(lyy,lmm,qq)

        
#==============
# Execution
#==============
if __name__ == '__main__': main()

以 上