def test_DB(): MA.set_window(150, 150) DB.set_data_folder('../data/') DB.set_span(datetime(2019, 1, 1), datetime(2019, 12, 31)) db = DB('sample.txt', 'Sample', '+', 8) eq_(db.db['APP_RATE'][0], 12) # 順序反転するので[0] は末尾 t = fileio.sn_fm_dt(datetime(2019, 2, 4)) ok_(12 < db.ma['APP_RATE'](t) < 78)
def test_gen_avg_dict(): MA.set_window(150, 150) DB.set_data_folder('../data/') DB.set_span(datetime(2019, 1, 1), datetime(2019, 12, 31)) db_list = [ DB('sample.txt', 'Sample', '+', 8), DB('sample1.txt', 'Sample', '+', 8), ] avg_dict = gen_avg_dict(db_list) t = fileio.sn_fm_dt(datetime(2019, 2, 15)) avg_dict['APP_RATE'](t)
def load_sorted(fn): """ 支持率/不支持率の読み込み。 Parameters ---------- fn, str : ファイル名(フルパス) Returns ------- buf, dict : 日時, 支持率, 不支持率 のリストの辞書 Notes ----- 各リストは日付順にソートしている """ data, names_ = fileio.load_core(fn) names = [_ for _ in names_ if _[:4] != 'DATE'] data = data[np.argsort(data['DATE1'])] # 日付でソート t1 = [fileio.sn_fm_dt(_) for _ in data['DATE1']] t2 = [fileio.sn_fm_dt(_) for _ in data['DATE2']] buf = {k:data[k] for k in names} buf['T'] = np.array([(a + b)/2 for (a, b) in zip(t1, t2)]) return buf
def __init__(self, fig): # DB 読み込み # DB の読み込み日付の指定. args = cfg['args'] d0 = _d(args.db_begin) df = _d(args.db_end) self.pp2, self.pp3, self.ppj = db_defs(d0, df, args.db_folder) # 評価日時 (10 日毎) self.t0 = sn_fm_dt(d0) self.tf = max(t_max(self.pp2), t_max(self.pp3), t_max(self.ppj)) + 10 self.tt = [a for a in range(int(self.t0), int(self.tf), 10) ] + [int(self.tf)] * 10 # 終端に tf を 10 回繰り返し。 # figure & axis 生成 # self.fig = fig self.ax = fig.add_subplot(1, 1, 1) self.fig.subplots_adjust(left=0) """
def main(): # オプション設定 (cfg['args'] に記録) # opt = options() cfg['args'] = opt.parse_args() args = cfg['args'] # DB 読み込み # DB の読み込み日付の指定. # ma_days [day] 感度解析のウィンドウ(直近 ma_days のデータから感度求める) # args = cfg['args'] d0 = _d(args.db_begin) df = _d(args.db_end) pp2, pp3, ppj = db_defs(d0, df, args.db_folder) ppa = ppj + pp2 + pp3 # ファクター設定 fc_dict = {} for yn in ['APP_RATE', 'NAP_RATE']: fc_dict[yn] = {} tstp = 10 tt = np.arange(t_min(ppa), t_max(ppa), tstp) ff_step = calc_fact(ppa, yn, tt, d_window=6*30) for p, f in zip(ppa, ff_step): fc_dict[yn][p.label] = interp(tt, f) # 補正後の平均 # for k in ['APP_RATE', 'NAP_RATE']: if args.k_days > 0: t0 = sn_fm_dt(d0) t_node = np.arange(t0, t_max(ppa) + 1, 1) # 移動平均を求める時刻 tven_buf[k] = trend_mav(fc_dict, k, t_node, ppa, w_days=30, k_days=args.k_days) else: t0 = sn_fm_dt(d0) t0_sunday = t0 + (6 - d0.weekday()) # 0:月曜 6:日曜 t_node = np.arange(t0_sunday, t_max(ppa) + 3, 7) # 移動平均を求める時刻 tven_buf[k] = trend_sunday(fc_dict, k, t_node, ppa) if 1: proc_trend() proc_trend_x(ppa, fc_dict) if 1: # 公表値/補正値/残差 fig, axes = plt.subplots(3, 2, figsize=(10, 7)) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.90, top=0.95, wspace=0.44) fig.text(0.20, 0.97, '支持する') if args.k_days > 0: fig.text(0.29, 0.62, '平均は指数移動平均') fig.text(0.29, 0.60, '(時定数 %d 日)' % args.k_days) else: fig.text(0.29, 0.62, '平均は日曜前後数日') proc_raw_cal_sdv(fc_dict, axes[:,0], 'APP_RATE', ppa) fig.text(0.70, 0.97, '支持しない') if args.k_days > 0: fig.text(0.75, 0.62, '平均は指数移動平均') fig.text(0.75, 0.60, '(時定数 %d 日)' % args.k_days) else: fig.text(0.75, 0.62, '平均は日曜前後数日') proc_raw_cal_sdv(fc_dict, axes[:,1], 'NAP_RATE', ppa) if args.gout: fig.savefig(os.path.join(args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 2, cfg['gout_date']))) if 1: proc_factor(ppa, 'APP_RATE', '内閣 支持率 感度係数', fc_dict, 3) proc_factor(ppa, 'NAP_RATE', '内閣 不支持率 感度係数', fc_dict, 4) # 表示 # イメージファイルの出力は proc_last() 内で行う # 複数の図を出力するアプリの plot.show() は一つなので main の最後で実施する if args.gout == False: plt.show()
def proc_factor(db_list, k_app_nap, k_title, fc_dict, gn_rel): """ 報道10 社の支持率/不支持率の調査感度の時系列比較 Parameters ---------- db_list, list of DB() k_app_nap, string : 分析データキー ('APP_RATE' or 'NAP_RATE') k_title, string : グラフタイトル fc_dict, - : 他の分析で使っている感度係数補間関数の辞書 gn_rel, : 出力図番の相対 """ args = cfg['args'] # 図の準備 nr = 6 fig, axes = plt.subplots(nr, 2, figsize=(10, 7)) fig.text(0.10, 0.97, k_title, fontsize=16) fig.text(0.60, 0.97, '(オレンジ:3ヵ月移動平均 ブルー:6ヵ月移動平均)', fontsize=12) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.95, top=0.95, wspace=0.25, hspace=0.25) # 分析期間 t0 = sn_fm_dt(_d(cfg['args'].db_begin)) tf = t_max(db_list) # 移動平均の窓幅をいくつか選んで感度のトレンドを描画(調査会社毎) for ndx, m in enumerate([3, 6]): # window size (m-month) tt = np.arange(t0 + 6*30, tf, 7) ff = calc_fact(db_list, k_app_nap, tt, m*30) dd = [dt_fm_sn(a) for a in tt] for j, (f, db) in enumerate(zip(ff, db_list)): c, r = divmod(j, nr) if ndx == 0: axes[r,c].plot(dd, f, color='orange', lw=2, alpha=0.8) else: axes[r,c].plot(dd, f, color='blue') fc = [fc_dict[k_app_nap][db.label](t) for t in tt] axes[r,c].plot(dd, fc, '-', color='green', alpha=0.5) axes[r,c].set_xlim(dd[0], dd[-1]+timedelta(days=30)) # タイトルや軸の設定 db_list_ax = db_list + ['']*(nr*2 - len(db_list)) print('db_list_ax', len(db_list_ax)) for j, db in enumerate(db_list_ax): c, r = divmod(j, nr) axes[r,c].set_xlim(dd[0], dd[-1]+timedelta(days=30)) if db != '': axes[r, c].set_ylabel(db.label) axes[r, c].set_ylim(0.8, 1.3) axes[r, c].grid(which='both') axes[r, c].grid(which='minor', alpha=0.1) if r == (nr - 1): print(r, c) set_date_tick(axes[r,c], (1, 7), '%Y/%m', 30) else: set_date_tick(axes[r,c], (1, 7), '%m', 0) # 調査が実施された日付をプロット if db != '': dd_org = [dt_fm_sn(a) for a in db.db['T']] oo_org = np.ones_like(dd_org) axes[r,c].plot(dd_org, oo_org, 'o', ms=4, alpha=0.2) if args.gout: fig.savefig(os.path.join(args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + gn_rel, cfg['gout_date'])))
def load(self, fn): a = load_sorted(os.path.join(self.data_folder, fn)) # T Y N ndx = (a['T'] >= fileio.sn_fm_dt(self.t0)) & (a['T'] <= fileio.sn_fm_dt(self.tf)) buf = {k: a[k][ndx] for k in a} return buf
def test_sn_fm_dt(): eq_(61, sn_fm_dt(datetime(1900, 3, 1)))
def main(): # オプション設定 (cfg['args'] に記録) # opt = options() cfg['args'] = opt.parse_args() args = cfg['args'] # DB 読み込み # DB の読み込み日付の指定. # ma_days [day] 感度解析のウィンドウ(直近 ma_days のデータから感度求める) # args = cfg['args'] d0 = _d(args.db_begin) df = _d(args.db_end) pp2, pp3, ppj = db_defs(d0, df, args.db_folder) # ファクター設定 fc_dict = {} for yn in ['APP_RATE', 'NAP_RATE']: fc_dict[yn] = {} for db_list in [ppj, pp2, pp3]: tstp = 10 tt = np.arange(t_min(db_list), t_max(db_list), tstp) ff_step = calc_fact(db_list, yn, tt, d_window=6 * 30) for db, f in zip(db_list, ff_step): fc_dict[yn][db.label] = interp(tt, f) # 補正後の平均 # t0 = sn_fm_dt(d0) t_node2 = np.arange(t0, t_max(pp2) + 1, 1) t_node3 = np.arange(t0, t_max(pp3) + 1, 1) t_nodej = np.arange(t0, t_max(ppj) + 1, 1) for k in ['APP_RATE', 'NAP_RATE']: if args.k_days > 0: tven_buf['H'][k] = trend_mav(fc_dict, k, t_node2, pp2, w_days=30, k_days=args.k_days) else: t0 = sn_fm_dt(d0) t0_sunday = t0 + (6 - d0.weekday()) # 0:月曜 6:日曜 t_node = np.arange(t0_sunday, t_max(pp2) + 3, 7) # 移動平均を求める時刻 tven_buf['H'][k] = trend_sunday(fc_dict, k, t_node, pp2) for k in ['APP_RATE', 'NAP_RATE']: if args.k_days > 0: tven_buf['L'][k] = trend_mav(fc_dict, k, t_node3, pp3, w_days=30, k_days=args.k_days) else: t0 = sn_fm_dt(d0) t0_sunday = t0 + (6 - d0.weekday()) # 0:月曜 6:日曜 t_node = np.arange(t0_sunday, t_max(pp3) + 3, 7) # 移動平均を求める時刻 tven_buf['L'][k] = trend_sunday(fc_dict, k, t_node, pp3) for k in ['APP_RATE', 'NAP_RATE']: if args.k_days > 0: tven_buf['J'][k] = trend_mav(fc_dict, k, t_nodej, ppj, w_days=30, k_days=args.k_days) else: t0 = sn_fm_dt(d0) t0_sunday = t0 + (6 - d0.weekday()) # 0:月曜 6:日曜 t_node = np.arange(t0_sunday, t_max(ppj) + 3, 7) # 移動平均を求める時刻 tven_buf['J'][k] = trend_sunday(fc_dict, k, t_node, ppj) if 1: proc_trend() if 1: # 公表値/補正値/残差 for yn in ['APP_RATE', 'NAP_RATE']: fig, axes = plt.subplots(3, 2, figsize=(10, 7)) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.90, top=0.95, wspace=0.44) fig.text(0.15, 0.97, '支持%s(グループH)' % { 'APP_RATE': 'する', 'NAP_RATE': 'しない' }[yn]) if args.k_days > 0: fig.text(0.29, 0.62, '平均は指数移動平均') fig.text(0.29, 0.60, '(時定数 %d 日)' % args.k_days) else: fig.text(0.29, 0.62, '平均は日曜前後数日') tt2, avg, err, num = tven_buf['H'][yn].by_column() proc_raw_cal_sdv(fc_dict, axes[:, 0], yn, pp2, tt2, avg) fig.text(0.65, 0.97, '支持%s(グループL)' % { 'APP_RATE': 'する', 'NAP_RATE': 'しない' }[yn]) if args.k_days > 0: fig.text(0.75, 0.62, '平均は指数移動平均') fig.text(0.75, 0.60, '(時定数 %d 日)' % args.k_days) else: fig.text(0.75, 0.62, '平均は日曜前後数日') tt3, avg, err, num = tven_buf['L'][yn].by_column() proc_raw_cal_sdv(fc_dict, axes[:, 1], yn, pp3, tt3, avg) if args.gout: if yn == 'APP_RATE': fig.savefig( os.path.join( args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 2, cfg['gout_date']))) else: fig.savefig( os.path.join( args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 3, cfg['gout_date']))) if 1: proc_yn(pp2, pp3, ppj) if 1: proc_fc(fc_dict, pp2, pp3, ppj) if 1: proc_hilo() # 表示 # イメージファイルの出力は proc_last() 内で行う # 複数の図を出力するアプリの plot.show() は一つなので main の最後で実施する if args.gout == False: plt.show()