6/30/2020
Analytics/smoothing.js at master · oluwafemi2016/Analytics · GitHub
oluwafemi2016 / Analytics
Code
Issues
Pull requests
Actions
Projects 1
Join GitHub today
Security
Insigh
Dismiss
GitHub is home to over 50 million developers
working together to host and review code, manage
projects, and build software together.
Sign up
master
Analytics / smoothing.js /
Jump to
oluwafemi2016 Create smoothing.js …
History
1 contributor
Raw
Blame
189 lines (167 sloc)
6.4 KB
1
// (A) SMOOTH ONLY
2
// This function smooths out fluctuations/noise in data, using exponential smoothing method
3
//Procedure & Important Notification
4
//a. First, the dataset is cleaned => NaNs are removed
5
//b. The cleaned dataset is then smoothened; stretch the smoothen array to avoid any potential wri
6
//c. Then with the known indices of NaNs (if available), intersperse NaNs into the smoothened arra
7
//d. In the provided function, the user loads the array and specifies the period of interest
8
//Note for user: "array" is dirty array to smooth; "size" is smoothing period
9
10
//Required dependency
11
const ema = require("moving-averages").ema
12
13
function smoothing(array, size) {
14
const array_clean = [];
15
array.forEach((val) => {
16
if (!isNaN(val)) {
https://github.com/oluwafemi2016/Analytics/blob/master/smoothing.js
1/5
6/30/2020
Analytics/smoothing.js at master · oluwafemi2016/Analytics · GitHub
17
array_clean.push(val);
18
}
19
});
20
const arr_length = array.length;
21
//smooth cleaned array
22
const array_smooth = ema(array_clean, size);
23
//Interpolate between smoothed data to fill interspersed NaNs
24
25
//Get Indices of all non-NaN elements and NaNs in dirty array
26
27
// get non nans
28
const IndexNNaN = [];
29
for (let j = 0; j < arr_length; j++) {
30
if (!isNaN(array[j])) {
31
IndexNNaN.push(array.indexOf(array[j]));
32
}
33
}
34
//get nans
35
const IndexNaN = [];
36
array.filter(function (arr, indx) {
37
if(isNaN(arr)){
38
IndexNaN.push(indx)
39
40
}
});
41
42
console.log("IndexNaN", IndexNaN);
43
console.log("IndexNNaN", IndexNNaN);
44
//Get the needed expansion size
45
const expand_size = IndexNNaN[IndexNNaN.length - 1] - IndexNNaN[0] + 1;
46
47
//Get the indices from first to last non-NaN interval
48
function GenArray(start, end, step) {
49
const xlist = [];
50
if (isNaN(step)) {
51
step = 1;
52
}
53
if (step > 0) {
54
for (let i = start; i <= end; i += step) {
55
xlist.push(i);
56
}
57
} else {
58
for (let i = start; i >= end; i += step) {
59
xlist.push(i);
60
}
61
}
62
return xlist;
63
}
64
const Index_Expand = GenArray(IndexNNaN[0], IndexNNaN[IndexNNaN.length - 1], 1);
https://github.com/oluwafemi2016/Analytics/blob/master/smoothing.js
2/5
6/30/2020
Analytics/smoothing.js at master · oluwafemi2016/Analytics · GitHub
65
66
//Piecewise linear interpolating function
67
function interpolateArray(data, fitCount) {
68
69
const linearInterpolate = function (before, after, atPoint) {
70
return before + (after - before) * atPoint;
71
};
72
73
const newData = Array();
74
const springFactor = ((data.length - 1) / (fitCount - 1));
75
newData[0] = data[0]; // for new allocation
76
for (let i = 1; i < fitCount - 1; i++) {
77
const tmp = i * springFactor;
78
const before = (Math.floor(tmp)).toFixed();
79
const after = (Math.ceil(tmp)).toFixed();
80
const atPoint = tmp - before;
81
newData[i] = linearInterpolate(data[before], data[after], atPoint);
82
}
83
newData[fitCount - 1] = data[data.length - 1]; // for new allocation
84
return newData;
85
};
86
const smooth_interp = interpolateArray(array_smooth, expand_size);
87
88
//Initial population of final array with NaNs;
89
const smooth_array = Array(arr_length).fill(NaN);
90
//splice smooth-interpolated array into smooth-array
91
for (let j = 0; j < Index_Expand.length; j++) {
92
smooth_array.splice(Index_Expand[j], 1, smooth_interp[j]);
93
}
94
//Now intersperse NaN, using IndexNaN, when IndexNaN.length > 0
95
for (let j = 0; j < IndexNaN.length; j++) {
96
smooth_array.splice(IndexNaN[j], 1, NaN);
97
}
98
return (smooth_array);
99
}
-
// For Testing Only
104
//const evg = ema([10, 12, 13, 40, 42, 45, 47], 2);
105
const A = [NaN, 1, 10, 12, 14,15, NaN, NaN, 16, 45, -12, NaN, NaN, 60, 55, 13, 23]
106
const arras = smoothing(A, 2)
107
console.log("arras", arras)
108
109
////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
110
//(B) SMOOTH AND INTERPOLATE
111
// This function smoothens the dataset and interpolates for NaNs in-between non-NaNs datapoints
112
// Not extrapolating to head and tail NaNs...
https://github.com/oluwafemi2016/Analytics/blob/master/smoothing.js
3/5
6/30/2020
Analytics/smoothing.js at master · oluwafemi2016/Analytics · GitHub
113
114
function smoothAndInterpolate(array, size) {
115
//Clean dirty array
116
const array_clean = [];
117
array.forEach((val) => {
118
if (!isNaN(val)) {
119
array_clean.push(val);
120
}
121
});
122
const arr_length = array.length;
123
//smooth cleaned array
124
const array_smooth = ema(array_clean, size);
125
//Interpolate between smoothed data to fill interspersed NaNs
126
127
//Get Indices of all non-NaN elements in dirty array
128
const Index = [];
129
for (let j = 0; j < arr_length; j++) {
130
if (!isNaN(array[j])) {
131
Index.push(array.indexOf(array[j]));
132
}
133
}
134
//Get the needed expansion size
135
const expand_size = Index[Index.length - 1] - Index[0] + 1;
136
137
//Get the indices from first to last non-NaN interval
138
function GenArray(start, end, step) {
139
const xlist = [];
140
if (isNaN(step)) {
141
step = 1;
142
}
143
if (step > 0) {
144
for (let i = start; i <= end; i += step) {
145
xlist.push(i);
146
}
147
} else {
148
for (let i = start; i >= end; i += step) {
149
xlist.push(i);
150
}
151
}
152
return xlist;
153
}
154
const Index_Expand = GenArray(Index[0], Index[Index.length - 1], 1);
155
156
//Piecewise linear interpolating function
157
function interpolateArray(data, fitCount) {
-
const linearInterpolate = function (before, after, atPoint) {
return before + (after - before) * atPoint;
https://github.com/oluwafemi2016/Analytics/blob/master/smoothing.js
4/5
6/30/2020
Analytics/smoothing.js at master · oluwafemi2016/Analytics · GitHub
161
};
162
163
const newData = Array();
164
const springFactor = ((data.length - 1) / (fitCount - 1));
165
newData[0] = data[0]; // for new allocation
166
for (let i = 1; i < fitCount - 1; i++) {
167
const tmp = i * springFactor;
168
const before = (Math.floor(tmp)).toFixed();
169
const after = (Math.ceil(tmp)).toFixed();
170
const atPoint = tmp - before;
171
newData[i] = linearInterpolate(data[before], data[after], atPoint);
172
}
173
newData[fitCount - 1] = data[data.length - 1]; // for new allocation
174
return newData;
175
};
176
const smooth_interp = interpolateArray(array_smooth, expand_size);
177
178
//Initial population of final array with NaNs;
179
const smooth_array = Array(arr_length).fill(NaN);
180
//splice smooth-interpolated array into smooth-array
181
for (let j = 0; j < Index_Expand.length; j++) {
182
smooth_array.splice(Index_Expand[j], 1, smooth_interp[j]);
183
}
184
return (smooth_array);
185
}
186
187
//Test2
188
const arras2 = smoothAndInterpolate(A, 2);
189
//console.log("arras2", arras2);
https://github.com/oluwafemi2016/Analytics/blob/master/smoothing.js
5/5