tspoon 0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tspoon-0.1/PKG-INFO ADDED
@@ -0,0 +1,3 @@
1
+ Metadata-Version: 2.1
2
+ Name: tspoon
3
+ Version: 0.1
tspoon-0.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
tspoon-0.1/setup.py ADDED
@@ -0,0 +1,20 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='tspoon',
5
+ version='0.1',
6
+ packages=find_packages(),
7
+ install_requires=[
8
+ # 'os',
9
+ # 'time',
10
+ # 'sys',
11
+ # 'pickle',
12
+ # 'pandas',
13
+ # 'numpy',
14
+ # 'regex',
15
+ # 'datetime',
16
+ # 'matplotlib',
17
+ # 'statsmodels',
18
+ # 'copy'
19
+ ]
20
+ )
@@ -0,0 +1 @@
1
+ from .main import *
@@ -0,0 +1,770 @@
1
+ ########################################################################################
2
+ #
3
+ # Utility fuctions - Date, Text, Time-series, Plotting
4
+ # Created by Beomseok Seo 2023.01.01
5
+ # Modified by Beomseok Seo 2024.01.01
6
+ #
7
+ ########################################################################################
8
+
9
+ import os, time, sys
10
+ import pickle
11
+ import pandas as pd
12
+ import numpy as np
13
+ import regex as re
14
+ import datetime as dt
15
+ from dateutil.relativedelta import relativedelta
16
+
17
+ import matplotlib.pyplot as plt
18
+ import statsmodels.api as sm
19
+ import copy
20
+
21
+ from statsmodels.tsa.filters.hp_filter import hpfilter
22
+ from statsmodels.tsa.x13 import x13_arima_analysis
23
+ from statsmodels.tsa.ar_model import AutoReg
24
+
25
+ #date functions
26
+
27
+ def firstdate(Y,m):
28
+ return dt.date(int(Y),int(m),1).strftime('%Y-%m-%d')
29
+
30
+ def lastdate(Y,m):
31
+ return (dt.date(int(Y),int(m),1)+relativedelta(months=1)-dt.timedelta(days=1)).strftime('%Y-%m-%d')
32
+
33
+ def datesbetween(startdate, enddate):
34
+ start_dt = dt.datetime.strptime(startdate,'%Y-%m-%d')
35
+ end_dt = dt.datetime.strptime(enddate,'%Y-%m-%d')
36
+ delta = dt.timedelta(days=1)
37
+
38
+ dates = []
39
+
40
+ while start_dt <= end_dt:
41
+ dates.append(start_dt.strftime('%Y-%m-%d'))
42
+ start_dt += delta
43
+
44
+ return dates
45
+
46
+ def daytrans(basedate):
47
+ return dt.date(int(basedate[:4]),int(basedate[4:6]),int(basedate[6:])).strftime('%Y-%m-%d')
48
+
49
+ def timetrans(basedate):
50
+ return dt.time(int(basedate[:2]),int(basedate[2:4]),int(basedate[4:])).strftime('%H:%M:%S')
51
+
52
+ def dayahead(basedate,dayahead):
53
+ if len(basedate) == 8:
54
+ return (dt.date(int(basedate[:4]),int(basedate[4:6]),int(basedate[6:]))-dt.timedelta(dayahead)).strftime('%Y%m%d')
55
+ elif len(basedate) == 10:
56
+ return (dt.date(int(basedate[:4]),int(basedate[5:7]),int(basedate[8:]))-dt.timedelta(dayahead)).strftime('%Y-%m-%d')
57
+
58
+ def dateexp(basedate):
59
+ return dt.date(int(basedate[:4]),int(basedate[5:7]),int(basedate[8:])).strftime('%Y.%m.%d')
60
+
61
+ def dayafter(basedate,dayahead):
62
+ return (dt.date(int(basedate[:4]),int(basedate[4:6]),int(basedate[6:]))+dt.timedelta(dayahead)).strftime('%Y%m%d')
63
+
64
+ def day2week(x, dformat='yyyy-mm-dd'):
65
+ if dformat=='yyyy-mm-dd':
66
+ isodate = dt.date(int(x[0:4]), int(x[5:7]), int(x[8:10])).isocalendar()
67
+ elif dformat=='yyyymmdd':
68
+ isodate = dt.date(int(x[0:4]), int(x[4:6]), int(x[6:8])).isocalendar()
69
+ return(str(isodate[0]*100+isodate[1]))
70
+
71
+ def day2month(x, dformat='yyyy-mm-dd'):
72
+ if dformat=='yyyy-mm-dd':
73
+ md = str(x)[0:4]+str(x)[5:7]
74
+ elif dformat=='yyyymmdd':
75
+ md = str(x)[0:4]+str(x)[4:6]
76
+ return(md)
77
+
78
+ def day2year(x):
79
+ yd = str(x)[0:4]
80
+ return(yd)
81
+
82
+ def month2quarter(x):
83
+ if str(x)[-2:] in ['01','02','03']:
84
+ qq = 'q1'
85
+ elif str(x)[-2:] in ['04','05','06']:
86
+ qq = 'q2'
87
+ elif str(x)[-2:] in ['07','08','09']:
88
+ qq = 'q3'
89
+ elif str(x)[-2:] in ['10','11','12']:
90
+ qq = 'q4'
91
+ mq = str(x)[:4]+qq
92
+ return(mq)
93
+
94
+ def quarter2month(x):
95
+ if str(x)[-2:] == 'q1':
96
+ mm = '03'
97
+ elif str(x)[-2:] == 'q2':
98
+ mm = '06'
99
+ elif str(x)[-2:] == 'q3':
100
+ mm = '09'
101
+ elif str(x)[-2:] == 'q4':
102
+ mm = '12'
103
+ mq = str(x)[:4]+mm
104
+ return(mq)
105
+
106
+ def week2day(x):
107
+ if (sys.version.split(' ')[0])>='3.8':
108
+ wd = dt.date.fromisocalendar(int(str(x)[0:4]), int(str(x)[5:7]), 1)
109
+ else:
110
+ wd = dt.datetime.strptime(str(x)[0:4]+'-W'+str(x)[4:6]+'-'+str(1), "%Y-W%W-%w")
111
+ return(wd.strftime('%Y-%m-%d'))
112
+
113
+ def month2day(x, day='first', dformat='yyyy-mm-dd'):
114
+ if day=='first':
115
+ md = dt.date(int(str(x)[0:4]),int(str(x)[4:6]),1)
116
+ elif day=='last':
117
+ md = dt.date(int(str(x)[0:4]),int(str(x)[4:6])+1,1)-dt.timedelta(dayahead)
118
+ if dformat=='yyyy-mm-dd':
119
+ return(md.strftime('%Y-%m-%d'))
120
+ elif dformat=='yyyymmdd':
121
+ return(md.strftime('%Y%m%d'))
122
+
123
+
124
+ def backwardMovingAverage(TS, lag_day=14, dd=None, todf=False):
125
+ if todf is True:
126
+ val = [np.mean(TS[i-lag_day+1:i+1]) for i in range(lag_day,len(TS))]
127
+ df = pd.DataFrame(val, index = TS.index[lag_day:])
128
+ return(df, None)
129
+ else:
130
+ return([np.mean(TS[i-lag_day+1:i+1]) for i in range(lag_day,len(TS))], dd[lag_day:])
131
+
132
+ def bMA(TS, lag_day=14, dd=None, todf=False):
133
+ if todf is True:
134
+ val = [np.mean(TS[i-lag_day+1:i+1]) for i in range(lag_day,len(TS))]
135
+ df = pd.DataFrame(val, index = TS.index[lag_day:])
136
+ return(df)
137
+ else:
138
+ return([np.mean(TS[i-lag_day+1:i+1]) for i in range(lag_day,len(TS))])
139
+
140
+ def cMA(TS, lag_day=14, lead_day=14, dd=None, todf=False):
141
+ if todf is True:
142
+ val = [np.mean(TS[i-lag_day+1:i+lead_day]) for i in range(lag_day,len(TS)-lead_day)]
143
+ df = pd.DataFrame(val, index = TS.index[lag_day:len(TS)-lead_day])
144
+ return(df)
145
+ else:
146
+ return([np.mean(TS[i-lag_day+1:i+1]) for i in range(lag_day,len(TS))])
147
+
148
+
149
+ def cutTimeSeries(TS,DTS, START_DAY='2020-01-01'):
150
+ dd_ = [dt.date(int(i[0:4]),int(i[5:7]),int(i[8:10])) for i in DTS]
151
+ dd_ = [i>dt.date(int(START_DAY[0:4]),int(START_DAY[5:7]),int(START_DAY[8:10])) for i in dd_]
152
+ return(np.array(TS)[dd_],np.array(DTS)[dd_])
153
+
154
+
155
+
156
+ def yoy(dat, period=12, smooth=None):
157
+ if smooth is not None:
158
+ base = cMA(dat, lag_day=smooth[0], lead_day=smooth[1], todf=True).shift(period)
159
+ return (dat/base*100-100).iloc[period:]
160
+ else:
161
+ return (dat/dat.shift(period)*100-100).iloc[period:]
162
+
163
+ def mom(dat, period=1):
164
+ return (dat/dat.shift(period)*100-100).iloc[period:]
165
+
166
+ def unyoy(dat_yoy, dat_level, period=52, smooth=None, max_iter=3, backward=False, backward_beginning_index=None):
167
+ if smooth is not None:
168
+ base = cMA(dat_level, lag_day=smooth[0], lead_day=smooth[1], todf=True).squeeze()
169
+ else:
170
+ base = dat_level
171
+
172
+ flag_f = dat_yoy.index == base.dropna().index[-1]
173
+ if np.any(flag_f):
174
+ base = pd.concat([base.loc[:base.dropna().index[-1]],pd.Series(np.nan, index=dat_yoy.index[np.where(flag_f)[0][0]+1:])])
175
+
176
+ k = dat_yoy.dropna().index[-1]
177
+
178
+ pred_level = ((dat_yoy+100)/100*base.shift(period))
179
+
180
+ i=1
181
+ while np.isnan(pred_level.loc[k]):
182
+ flag = pred_level.index == base.dropna().index[-1]
183
+ base = pd.concat([base.loc[:base.dropna().index[-1]], pred_level.iloc[np.where(flag)[0][0]+1:]])
184
+ pred_level = ((dat_yoy+100)/100*base.shift(period))
185
+ i+=1
186
+ if i >max_iter:
187
+ raise Exception("Something is wrong in the iteration of computing pred_level!")\
188
+
189
+ pred_level[base.index[:period]] = base.iloc[:period]
190
+
191
+ if backward:
192
+ flag_b = dat_yoy.index == base.dropna().index[0]
193
+
194
+ if np.any(flag_b):
195
+ base = pd.concat([pd.Series(np.nan, index=dat_yoy.index[:np.where(flag_b)[0][0]]), base.loc[base.dropna().index[0]:]])
196
+
197
+ k = dat_yoy.dropna().index[0]
198
+
199
+ if backward_beginning_index is not None:
200
+ pred_level = pd.concat([pd.Series(np.nan, index=backward_beginning_index), pred_level])
201
+ dat_yoy = pd.concat([pd.Series(np.nan, index=backward_beginning_index), dat_yoy])
202
+ base = pd.concat([pd.Series(np.nan, index=backward_beginning_index), base])
203
+ flag_b = list([False for i in range(len(backward_beginning_index))]) + list(flag_b)
204
+
205
+ if dat_yoy.dropna().index[0] == dat_yoy.index[0]:
206
+ k = backward_beginning_index[0]
207
+ else:
208
+ k = dat_yoy.index[max(0,np.where(dat_yoy.index==dat_yoy.dropna().index[0])[0][0]-period)]
209
+
210
+ pred_level_back = (base/((dat_yoy+100)/100)).shift(-period)
211
+
212
+ i=1
213
+ while np.isnan(pred_level_back.loc[k]):
214
+ flag = pred_level_back.index == base.dropna().index[0]
215
+ base = pd.concat([pred_level_back.iloc[:np.where(flag)[0][0]], base.loc[base.dropna().index[0]:]])
216
+ pred_level_back = (base/((dat_yoy+100)/100)).shift(-period)
217
+ i+=1
218
+ if i >max_iter:
219
+ raise Exception("Something is wrong in the iteration of computing pred_level!")
220
+
221
+ pred_level[dat_yoy.index[:np.where(flag_b)[0][0]]] = pred_level_back.loc[dat_yoy.index[:np.where(flag_b)[0][0]]]
222
+
223
+ return pred_level
224
+
225
+ def naoutlier(df, quantile=0.99):
226
+ q = df.quantile(quantile)
227
+ return df[df < q]
228
+
229
+ # dataframe function
230
+
231
+ def GenDf_w2m(df_w, aggregate='last'):
232
+ df_wm = copy.deepcopy(df_w)
233
+ df_wm.index = [day2month(week2day(x)) for x in df_wm.index]
234
+ df_wm.index.name = 'index'
235
+ if aggregate=='last':
236
+ df_m = df_wm[~df_wm.index.duplicated(keep='last')]
237
+ if aggregate=='mean':
238
+ df_m = df_wm.groupby('index').mean()
239
+ elif aggregate=='max':
240
+ df_m = df_wm.groupby('index').max()
241
+ elif aggregate=='median':
242
+ df_m = df_wm.groupby('index').median()
243
+ return df_m
244
+
245
+ def GenDf_m2w(df_w,df_m,interpolate='linear'):
246
+
247
+ if df_w is None:
248
+
249
+ firstmon = df_m.index[0]
250
+ lastmon = df_m.index[-1]
251
+
252
+ start_dt = firstdate(firstmon[:4],firstmon[4:])
253
+ end_dt = lastdate(lastmon[:4],lastmon[4:])
254
+
255
+ weeks = uniq([day2week(x) for x in datesbetween(start_dt, end_dt)])
256
+ df_w = pd.DataFrame(index=weeks)
257
+
258
+
259
+ df_mw = pd.DataFrame(index = [day2month(week2day(x)) for x in df_w.index], columns = df_m.columns)
260
+ df_mw_index = np.array([int(x) for x in df_mw.index])
261
+ month_loc = np.where([x>0 for x in df_mw_index[1:] - df_mw_index[:-1]]+[True])[0]
262
+ df_mw.index = df_w.index
263
+
264
+ try:
265
+ df_mw.iloc[month_loc] = df_m.loc[[str(x) for x in df_mw_index[month_loc]],:]
266
+ except:
267
+ for m in month_loc:
268
+ try:
269
+ df_mw.iloc[m] = df_m.loc[str(df_mw_index[m]),:]
270
+ except:
271
+ continue
272
+
273
+ if interpolate=='linear':
274
+ return df_mw.apply(pd.to_numeric).interpolate('linear', limit_area='inside')
275
+ else:
276
+ return df_mw.apply(pd.to_numeric)
277
+
278
+ def GenDf_q2m(df_q,interpolate='linear'):
279
+ df_q.index = [str(x) for x in df_q.index]
280
+ df_q.index = [x.replace('Q','q') for x in df_q.index]
281
+
282
+ df_qm = pd.DataFrame(index = [str(x)+str(y+100)[-2:] for x in uniq([z[:4] for z in df_q.index]) for y in range(1,13)],
283
+ columns = df_q.columns)
284
+ df_qm = df_qm.loc[quarter2month(df_q.index[0]):quarter2month(df_q.index[-1])]
285
+ quarter_loc = np.where([x[-2:] in ('03','06','09','12') for x in df_qm.index])[0]
286
+
287
+ try:
288
+ df_qm.iloc[quarter_loc] = df_q.loc[[month2quarter(x) for x in df_qm.index[quarter_loc]],:]
289
+ except:
290
+ for q in quarter_loc:
291
+ try:
292
+ df_qm.iloc[q] = df_q.loc[month2quarter(df_qm.index[q]),:]
293
+ except:
294
+ continue
295
+
296
+ if interpolate=='linear':
297
+ return df_qm.apply(pd.to_numeric).interpolate('linear', limit_area='inside')
298
+ else:
299
+ return df_qm.apply(pd.to_numeric)
300
+
301
+ def GenDf_m2q(df_m, aggregate='last'):
302
+ df_mq = copy.deepcopy(df_m)
303
+ df_mq.index = [month2quarter(x) for x in df_mq.index]
304
+ df_mq.index.name = 'index'
305
+ if aggregate=='last':
306
+ df_q = df_mq[~df_mq.index.duplicated(keep='last')]
307
+ if aggregate=='mean':
308
+ df_q = df_mq.groupby('index').mean()
309
+ elif aggregate=='max':
310
+ df_q = df_mq.groupby('index').max()
311
+ elif aggregate=='median':
312
+ df_q = df_mq.groupby('index').median()
313
+ elif aggregate=='sum':
314
+ df_q = df_mq.groupby('index').sum()
315
+ return df_q
316
+
317
+ def GenDf_y2m(df_y,interpolate='linear'):
318
+ df_y.index = [str(x) for x in df_y.index]
319
+ df_ym = pd.DataFrame(index = [str(x)+str(y+100)[-2:] for x in df_y.index for y in range(1,13)], columns = df_y.columns)
320
+ df_ym_index = np.array([int(x[:4]) for x in df_ym.index])
321
+ year_loc = np.where([x>0 for x in df_ym_index[1:] - df_ym_index[:-1]]+[True])[0]
322
+
323
+ try:
324
+ df_ym.iloc[year_loc] = df_y.loc[[str(x) for x in df_ym_index[year_loc]],:]
325
+ except:
326
+ for y in year_loc:
327
+ try:
328
+ df_ym.iloc[y] = df_y.loc[str(df_ym_index[y]),:]
329
+ except:
330
+ continue
331
+
332
+ if interpolate=='linear':
333
+ return df_ym.apply(pd.to_numeric).interpolate('linear', limit_area='inside')
334
+ else:
335
+ return df_ym.apply(pd.to_numeric)
336
+
337
+ def GenMonthDummy(index, MW='week', num_month=13):
338
+ if MW == 'week':
339
+ month_dummy = pd.get_dummies([int(day2month(week2day(x))[-2:]) for x in index])
340
+ month_dummy.index = index
341
+ # month_dummy = pd.DataFrame(0,index = index, columns = range(1,num_month))
342
+ # for i,m in enumerate([int(day2month(week2day(x))[-2:]) for x in month_dummy.index]):
343
+ # month_dummy.loc[month_dummy.index[i],m] = 1
344
+ elif MW == 'month':
345
+ month_dummy = pd.get_dummies([int(x[-2:]) for x in index])
346
+ month_dummy.index = index
347
+ # month_dummy = pd.DataFrame(0,index = index, columns = range(1,num_month))
348
+ # for i,m in enumerate([int(x[-2:]) for x in month_dummy.index]):
349
+ # month_dummy.loc[month_dummy.index[i],m] = 1
350
+
351
+ month_dummy.columns = [str(x) for x in month_dummy.columns]
352
+ return month_dummy
353
+
354
+ def GenYearDummy(index, MW='week'):
355
+ year_dummy = pd.get_dummies([x[:4] for x in index])
356
+ year_dummy.index = index
357
+ year_dummy.columns = [str(x) for x in year_dummy.columns]
358
+ return year_dummy
359
+ # year_dummy = pd.DataFrame(index = index)
360
+ # for i,y in enumerate(np.unique([x[:4] for x in index])):
361
+ # year_dummy = pd.concat([year_dummy, \
362
+ # pd.DataFrame(1,index=[x for x in index if str(x[:4])==str(y)], \
363
+ # columns=[str(y)])],\
364
+ # axis=1)
365
+ # year_dummy.columns = [str(x) for x in year_dummy.columns]
366
+ # return year_dummy.fillna(0)
367
+
368
+ def GenStructBreakDummy(index, time, time2=None, MW='week'):
369
+ if MW == 'week':
370
+ structbreak_dummy = pd.DataFrame(0,index = index, columns = ['sb'])
371
+ if time2 is None:
372
+ structbreak_dummy.loc[structbreak_dummy.index>=str(time),'sb'] = 1
373
+ else:
374
+ structbreak_dummy.loc[(structbreak_dummy.index>=str(time)) & (structbreak_dummy.index<=str(time2)),'sb'] = 1
375
+ elif MW == 'month':
376
+ structbreak_dummy = pd.DataFrame(0,index = index, columns = ['sb'])
377
+ if time2 is None:
378
+ structbreak_dummy.loc[structbreak_dummy.index>=str(time),'sb'] = 1
379
+ else:
380
+ structbreak_dummy.loc[(structbreak_dummy.index>=str(time)) & (structbreak_dummy.index<=str(time2)),'sb'] = 1
381
+
382
+ structbreak_dummy.columns = [str(x) for x in structbreak_dummy.columns]
383
+ return structbreak_dummy
384
+
385
+ def GenCountDummy(index, holiday, holiday_counts):
386
+ holiday_dummy = pd.DataFrame(0,index=index,columns=['h'])
387
+ for i,h in enumerate(holiday):
388
+ holiday_dummy.loc[h,'h'] = holiday_counts[i]
389
+ holiday_dummy = holiday_dummy.loc[index]
390
+ return holiday_dummy
391
+
392
+ # data check fuction
393
+
394
+ def uniq(ls):
395
+ seen = set()
396
+ uniq = [x for x in ls if x not in seen and not seen.add(x)]
397
+ return uniq
398
+
399
+ def dupes(ls):
400
+ seen = set()
401
+ dupes = [x for x in ls if x in seen or seen.add(x)]
402
+ return dupes
403
+
404
+ # text function
405
+
406
+ def Arti2Sents(doc):
407
+ return([p for w in doc for p in w.split('. ')])
408
+
409
+ def Arti2SentsGroup(doc):
410
+ return([w.split('. ') for w in doc])
411
+
412
+ def Arrange2Article(results):
413
+ return [[item for sublist in res for item in sublist] for res in results]
414
+
415
+ def Arrange2Sentence(results):
416
+ return [item for sublist in results for item in sublist], [i for i,sublist in enumerate(results) for _ in sublist]
417
+
418
+ def WordCheck0(content,words_list):
419
+ return any([re.search(w,content)!=None for w in words_list])
420
+
421
+ def WordCheck1(content,words_list_by_groups):
422
+ return all([any([re.search(w,content)!=None for w in Words]) for Words in words_list_by_groups])
423
+
424
+ def WordCheck2(content,words_list_by_groups,words_negation):
425
+ return all([any([re.search(w,content)!=None for w in Words]) for Words in words_list_by_groups]+[re.search(w,content)==None for w in words_negation])
426
+
427
+ def Arti2Sents(doc):
428
+ delim = ['┃ ','→ ','— ',' ','! ','? ','•','○','●','◎','◇','◆','□','■','▷','▶','◈','▣',
429
+ '\uf0a7','\uf0d8','\uf076','\uf077','\uf06c','\uf09f']
430
+ p = []
431
+ for w in doc:
432
+ for d in delim:
433
+ w = w.replace(d,'. ')
434
+ p+=w.split('. ')
435
+ return(p)
436
+ #return([p for w in doc for p in w.replace('┃ ','. ').replace('• ','. ').replace('— ','. ').replace(' ','. ').replace('! ','. ').replace('? ','. ').split('. ')])
437
+
438
+ def Arti2SentsGroup(doc):
439
+ delim = ['┃ ','→ ','— ',' ','! ','? ','•','○','●','◎','◇','◆','□','■','▷','▶','◈','▣',
440
+ '\uf0a7','\uf0d8','\uf076','\uf077','\uf06c','\uf09f']
441
+ p = []
442
+ for w in doc:
443
+ for d in delim:
444
+ w = w.replace(d,'. ')
445
+ p.append(w.split('. '))
446
+ return(p)
447
+
448
+ def Arrange2Article(results):
449
+ return [[item for sublist in res for item in sublist] for res in results]
450
+
451
+
452
+
453
+ #pad and cut
454
+
455
+ def IntEncode(tokenized_sents, vocab): return [y+1 for y in vocab.doc2idx(tokenized_sents)]
456
+
457
+ def PadNCut(encoded_sents, maxlen): return np.array(np.pad(encoded_sents,[maxlen-min(len(encoded_sents),maxlen),0],'constant')[:maxlen])
458
+
459
+
460
+
461
+ #criteria functions
462
+
463
+ def rmse(y_pred,y_true): return np.sqrt(np.mean((y_pred-y_true)**2))
464
+
465
+ def mae(y_pred,y_true): return np.mean(np.abs(y_pred-y_true))
466
+
467
+
468
+
469
+ #transformation functions
470
+
471
+ def x13as(df, period='M', X12PATH='D:/x1.programs/x13as/'):
472
+ df.dropna(inplace=True)
473
+ ind = df.index
474
+ col = df.columns[0]
475
+ df.index = pd.PeriodIndex(df.index, freq=period)
476
+ df.columns = ['temp']
477
+ df = x13_arima_analysis(df, x12path=X12PATH).seasadj.to_frame(col)
478
+ df.index = ind
479
+ return df
480
+
481
+ def hp(df, period='M', lamb=None):
482
+ if lamb != None:
483
+ return sm.tsa.filters.hp_filter.hpfilter(x, lamb=lamb)
484
+ if period == 'D':
485
+ lamb = 1600*((365/4)**4)
486
+ elif period == 'W':
487
+ lamb = 1600*((52/4)**4)
488
+ elif period == 'M':
489
+ lamb = 129600 # or 14400
490
+ elif period == 'Q':
491
+ lamb = 1600
492
+ elif period == 'Y':
493
+ lamb = 6.25 # 100 for half-yearly
494
+ return sm.tsa.filters.hp_filter.hpfilter(x, lamb=lamb)
495
+
496
+ def extrapolate(df, maxlags=1):
497
+ df_ = df.copy()
498
+ df = copy.deepcopy(df.loc[df.dropna(axis=0).index[0]:])
499
+
500
+ if df.isna().sum().sum() == 0:
501
+ return df
502
+
503
+ if df.shape[1] == 1:
504
+ df_train = df.dropna()
505
+ df_test = df[df.isna().sum(axis=1)>0]
506
+
507
+ df_test[df_test.columns[0]] = AutoReg(endog=df_train, lags=maxlags)\
508
+ .fit().forecast(df_test.shape[0]).values
509
+ df.loc[df_test.index] = df_test
510
+ df_.loc[df.index] = df
511
+ return df_
512
+ else:
513
+ col_id_nan = np.where(df.dropna(axis=0,how='all').isna().sum(axis=0)>0)[0]
514
+ for i in col_id_nan:
515
+ df_train = df.dropna()
516
+ df_test = df[df.iloc[:,i].isna()]
517
+
518
+ forc = AutoReg(endog=df_train.iloc[:,[i]],\
519
+ exog=df_train.drop(df_train.columns[col_id_nan], axis=1), lags=maxlags)\
520
+ .fit().forecast(df_test.shape[0],\
521
+ exog=df_test.drop(df_train.columns[col_id_nan], axis=1)).values
522
+ df.iloc[:,i].loc[df_test.index] = forc
523
+ df_.loc[df.index] = df
524
+
525
+ # df_train = df.dropna()
526
+ # df_test = df[df.isna().sum(axis=1)>0]
527
+
528
+ # df_test[df_test.columns[0]] = AutoReg(endog=df_train.iloc[:,[0]],\
529
+ # exog=df_train.iloc[:,1:], lags=maxlags)\
530
+ # .fit().forecast(df_test.shape[0],\
531
+ # exog=df_test.iloc[:,1:]).values
532
+ # df.loc[df_test.index] = df_test
533
+ # df_.loc[df.index] = df
534
+ return df_
535
+
536
+ def proportion(df):
537
+ return (df.T/df.sum(axis=1)*100).T
538
+
539
+ def contribution(df, period=12):
540
+ # return (df.T/df.shift(period).sum(axis=1).T).T
541
+ return ((df-df.shift(period)).T/df.shift(period).sum(axis=1)).T
542
+
543
+ def contribution_proportion(df, period=12):
544
+ return ((df-df.shift(period)).T/(df.sum(axis=1)-df.shift(period).sum(axis=1))).T
545
+
546
+ def norm(pdx): return (pdx-pdx.mean())/pdx.std()
547
+ def scale(pdx): return (pdx-pdx.min())/(pdx.max()-pdx.min())
548
+ def linintp(pdx): return pdx.interpolate(method='linear')
549
+ def hptrend(lst,lamb=1): return sm.tsa.filters.hp_filter.hpfilter(lst, lamb=lamb)[1]
550
+ def hpcycle(lst,lamb=1): return sm.tsa.filters.hp_filter.hpfilter(lst, lamb=lamb)[0]
551
+ # def hmtrend(lst, hint=12): return qe.hamilton_filter(lst.values, hint)[1]
552
+ # def hmcycle(lst, hint=12): return qe.hamilton_filter(lst.values, hint)[0]
553
+
554
+ def unnorm(pdx,m,s): return pdx*s+m
555
+
556
+
557
+ def ifexist(df, var, error_return=None):
558
+ if type(df)==dict:
559
+ if var in df.keys():
560
+ return df[var]
561
+ else:
562
+ return error_return
563
+ elif type(df)==pd.DataFrame:
564
+ if var in df.columns:
565
+ return df[var]
566
+ else:
567
+ return error_return
568
+
569
+ #memory functions
570
+
571
+ def sizeof_fmt(num, suffix='B'):
572
+ ''' by Fred Cirera, https://stackoverflow.com/a/1094933/1870254, modified'''
573
+ for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
574
+ if abs(num) < 1024.0:
575
+ return "%3.1f %s%s" % (num, unit, suffix)
576
+ num /= 1024.0
577
+ return "%.1f %s%s" % (num, 'Yi', suffix)
578
+
579
+ # plotting functions
580
+
581
+ def Hangul(fontpath = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'):
582
+ from matplotlib.font_manager import fontManager, FontProperties
583
+ from matplotlib import rcParams
584
+
585
+ fontManager.addfont(fontpath)
586
+ fontprop = FontProperties(fname=fontpath, size=10)
587
+ fontname = fontprop.get_name()
588
+
589
+ rcParams['font.family'] = fontname
590
+ rcParams['axes.unicode_minus'] =False
591
+
592
+ def Plotly(df, color=None, theme=None, dropdown=False):
593
+ pd.options.plotting.backend = "plotly"
594
+ if color is not None:
595
+ fig = df.plot(color_discrete_map=color)
596
+ else:
597
+ fig = df.plot()
598
+
599
+ myupdatemenus=[
600
+ dict(
601
+ type = "buttons",
602
+ buttons=list([
603
+ dict(
604
+ args=["visible", "legendonly"],
605
+ label="Deselect All",
606
+ method="restyle"
607
+ ),
608
+ dict(
609
+ args=["visible", True],
610
+ label="Select All",
611
+ method="restyle"
612
+ )
613
+ ]),
614
+ direction = "right",
615
+ showactive= True,
616
+ pad={"r": 10, "t": 10},
617
+ x=0.9,
618
+ xanchor="left",
619
+ y=1.12,
620
+ yanchor="top"
621
+ ),
622
+ ]
623
+ fig.update_layout(dict(updatemenus = myupdatemenus))
624
+
625
+ if theme=='white':
626
+ fig.update_layout(
627
+ plot_bgcolor='white'
628
+ )
629
+ fig.update_xaxes(
630
+ mirror=True,
631
+ ticks='outside',
632
+ showline=True,
633
+ linecolor='black',
634
+ gridcolor='lightgrey'
635
+ )
636
+ fig.update_yaxes(
637
+ mirror=True,
638
+ ticks='outside',
639
+ showline=True,
640
+ linecolor='black',
641
+ gridcolor='lightgrey'
642
+ )
643
+ fig.update_layout(
644
+ xaxis_title="", yaxis_title=""
645
+ )
646
+
647
+ if dropdown:
648
+ add1updatemenus = [
649
+ dict(buttons= [dict(
650
+ method= 'restyle',
651
+ label= str(i),
652
+ args= [{'x':[[z for z in df[y].index if int(z)>=int(i)] for y in df],
653
+ 'y': [df[y][[z for z in df[y].index if int(z)>=int(i)]] for y in df]}]
654
+ ) for i in df.index],
655
+ direction= 'down',
656
+ showactive= True,
657
+ pad={"r": 10, "t": 10},
658
+ x=0.0,
659
+ xanchor="left",
660
+ y=1.12,
661
+ yanchor="top"
662
+ )
663
+ ]
664
+ add2updatemenus = [
665
+ dict(buttons= [dict(
666
+ method= 'restyle',
667
+ label= str(i),
668
+ args= [{'x':[[z for z in df[y].index if int(z)<=int(i)] for y in df],
669
+ 'y': [df[y][[z for z in df[y].index if int(z)<=int(i)]] for y in df]}]
670
+ ) for i in df.index],
671
+ direction= 'down',
672
+ showactive= True,
673
+ pad={"r": 10, "t": 10},
674
+ x=0.15,
675
+ xanchor="left",
676
+ y=1.12,
677
+ yanchor="top"
678
+ )
679
+ ]
680
+
681
+
682
+ fig.update_layout(dict(updatemenus = myupdatemenus+add1updatemenus+add2updatemenus))
683
+ pass
684
+
685
+
686
+ fig.show()
687
+
688
+ def plotly_theme(fig, legend_x=0.65, legend_y=0.05, fs=20, legend_orientation='v', fs_legend=None, \
689
+ tickangle_x=90, title_x=None, title_y=None, range_y=None, margin=dict(l=10, r=30, t=30, b=10),\
690
+ left_unit=None, right_unit=None ):
691
+
692
+ if fs_legend is None:
693
+ fs_legend = fs
694
+
695
+ fig.update_layout(
696
+ legend=dict(
697
+ x=legend_x,
698
+ y=legend_y,
699
+ traceorder="normal",
700
+ title=None,
701
+ orientation=legend_orientation,
702
+ font=dict(
703
+ size=fs_legend,
704
+ #family="sans-serif",
705
+ #color="black"
706
+ ),
707
+ )
708
+ )
709
+ fig.update_layout(
710
+ margin=margin,
711
+ plot_bgcolor='white',
712
+ font=dict(size=fs)
713
+ )
714
+ fig.update_xaxes(
715
+ mirror=True,
716
+ ticks='outside',
717
+ showline=True,
718
+ linecolor='black',
719
+ tickangle=tickangle_x,
720
+ #gridcolor='lightgrey'
721
+ )
722
+ fig.update_yaxes(
723
+ mirror=True,
724
+ ticks='outside',
725
+ showline=True,
726
+ linecolor='black',
727
+ #gridcolor='lightgrey'
728
+ )
729
+ fig.update_layout(
730
+ xaxis_title=title_x,
731
+ yaxis_title=title_y,
732
+ )
733
+ if range_y is not None:
734
+ fig.update_yaxes(
735
+ range=range_y
736
+ )
737
+
738
+ if left_unit is not None:
739
+ fig.add_annotation(dict(font=dict(color="black",size=left_unit.get('fs', fs)),
740
+ x=0, y=1.01,
741
+ showarrow=False,
742
+ text=left_unit['text'],
743
+ xanchor='left',
744
+ yanchor='bottom',
745
+ textangle=0,
746
+ xref="paper",
747
+ yref="paper"
748
+ ))
749
+
750
+ if right_unit is not None:
751
+ fig.add_annotation(dict(font=dict(color="black",size=right_unit.get('fs', fs)),
752
+ x=1, y=1.01,
753
+ showarrow=False,
754
+ text=right_unit['text'],
755
+ xanchor='right',
756
+ yanchor='bottom',
757
+ textangle=0,
758
+ xref="paper",
759
+ yref="paper"
760
+ ))
761
+
762
+ # fig.add_trace(go.Scatter(
763
+ # x=[-1],
764
+ # y=[1.5],
765
+ # mode="text",
766
+ # name="",
767
+ # text=["(%p)"],
768
+ # textposition="top center"
769
+ # ))
770
+ # fig.show()
@@ -0,0 +1,3 @@
1
+ Metadata-Version: 2.1
2
+ Name: tspoon
3
+ Version: 0.1
@@ -0,0 +1,7 @@
1
+ setup.py
2
+ tspoon/__init__.py
3
+ tspoon/main.py
4
+ tspoon.egg-info/PKG-INFO
5
+ tspoon.egg-info/SOURCES.txt
6
+ tspoon.egg-info/dependency_links.txt
7
+ tspoon.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ tspoon