This repository has been archived by the owner on Oct 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex-1.js
89 lines (74 loc) · 3.24 KB
/
index-1.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
var Stopwatch = require('statman-stopwatch');
var stopwatch = new Stopwatch();
stopwatch.start();
const dataForge = require('data-forge');
const moment = require('moment');
const data = [
{ date: moment().toDate(), value: 1 },
{ date: moment().add(1, 'days').toDate(), value: 3 },
{ date: moment().add(5, 'days').toDate(), value: 2 },
{ date: moment().add(6, 'days').toDate(), value: 6 },
{ date: moment().add(7, 'days').toDate(), value: 5 },
{ date: moment().add(12, 'days').toDate(), value: 2 },
{ date: moment().add(15, 'days').toDate(), value: 9 },
];
const df = new dataForge.DataFrame(data).setIndex('date');
const gapExists = (pairA, pairB) => {
// Return true if there is a gap longer than a day.
// Log when we enter this function
console.log('gapExists [pairA, pairB]', [pairA, pairB]);
const startDate = pairA[1].date;
const endDate = pairB[1].date;
const gapSize = moment(endDate).startOf('day').diff(moment(startDate).startOf('day'), 'days');
return gapSize > 1;
};
const gapFiller = (pairA, pairB) => {
const startDate = pairA[1].date;
const endDate = pairB[1].date;
const gapSize = moment(endDate).startOf('day').diff(moment(startDate).startOf('day'), 'days');
const numEntries = gapSize - 1;
const newEntries = [];
for (let entryIndex = 0; entryIndex < numEntries; entryIndex += 1) {
const newValue = { date: pairA[1].date, value: pairA[1].value };
newValue.date = moment(pairA[1].date).add(entryIndex + 1, 'days').toDate();
newEntries.push([
moment(pairA[0]).add(entryIndex + 1, 'days').toDate(), // New index
newValue, // New value
]);
}
return newEntries;
};
// In this case, the final value of dfWithoutGaps is
// what you'd expect and the number of entries into
// gapExists is about what I'd expect.
//
// I say "about" what I'd expect because there are
// two seemingly identical comparisons made between the
// first two items of the data set for a total
// execution count of 7 when I'd expect 6.
const dfWithoutGaps = df.fillGaps(gapExists, gapFiller);
console.log('dfWithoutGaps', dfWithoutGaps.toArray());
// With the following line uncommented the rollingWindow
// call below will trigger a huge number of calls to
// gapExists (I'm not sure how many but enough to max out the
// buffer in my browser's debug console). It appears as if
// fillGaps is being run for each rolling window.
//
// The speed of generating the rolling window in this
// scenario is very slow.
// const mySeries = dfWithoutGaps.getSeries('value');
// If we force the lazy evaluation via the line below and then
// run rollingWindow we'll get the expected number of calls (6) to
// gapExists.
//
// The speed of generating the rolling window in this scenario
// is very fast.
// https://github.com/data-forge/data-forge-ts/blob/master/docs/guide.md#lazy-evaluation-through-iterators
const mySeries = new dataForge.Series(dfWithoutGaps.getSeries('value').toArray());
const smaPeriod = 3;
const smaSeries = mySeries
.rollingWindow(smaPeriod)
.select(window => window.sum() / smaPeriod);
console.log('smaSeries', smaSeries.toArray());
stopwatch.stop();
console.log("Time [1]: " + stopwatch.read());