|
1 | | -#-----------------------------------------------------# StatCollection (Series and Group) |
2 | | -abstract type StatCollection{T} <: OnlineStat{T} end |
3 | | - |
4 | | -function Base.show(io::IO, o::StatCollection) |
5 | | - print(io, name(o, false, false)) |
6 | | - print_stat_tree(io, o.stats) |
7 | | -end |
8 | | - |
9 | | -function print_stat_tree(io::IO, stats) |
10 | | - for (i, stat) in enumerate(stats) |
11 | | - char = i == length(stats) ? '└' : '├' |
12 | | - print(io, "\n $(char)── $stat") |
13 | | - end |
14 | | -end |
15 | | - |
16 | 1 | #-----------------------------------------------------------------------# AutoCov and Lag |
17 | 2 | # Lag |
18 | 3 | """ |
@@ -206,12 +191,6 @@ nkeys(o::CountMap) = length(o.value) |
206 | 191 | Base.values(o::CountMap) = values(o.value) |
207 | 192 | Base.getindex(o::CountMap, i) = o.value[i] |
208 | 193 |
|
209 | | -#-----------------------------------------------------------------------# Counter |
210 | | -mutable struct Counter <: OnlineStat{Any} |
211 | | - n::Int |
212 | | -end |
213 | | -_fit!(o::Counter) = (o.n += 1) |
214 | | - |
215 | 194 | #-----------------------------------------------------------------------# CovMatrix |
216 | 195 | """ |
217 | 196 | CovMatrix(p=0; weight=EqualWeight()) |
@@ -307,109 +286,6 @@ end |
307 | 286 | Base.last(o::Diff) = o.lastval |
308 | 287 | Base.diff(o::Diff) = o.diff |
309 | 288 |
|
310 | | - |
311 | | -#-----------------------------------------------------------------------# Extrema |
312 | | -""" |
313 | | - Extrema(T::Type = Float64) |
314 | | -
|
315 | | -Maximum and minimum. |
316 | | -
|
317 | | -# Example |
318 | | -
|
319 | | - o = fit!(Extrema(), rand(10^5)) |
320 | | - extrema(o) |
321 | | - maximum(o) |
322 | | - minimum(o) |
323 | | -""" |
324 | | -# T is type to store data, S is type of single observation. |
325 | | -# E.g. you may want to accept any Number even if you are storing values as Float64 |
326 | | -mutable struct Extrema{T,S} <: OnlineStat{S} |
327 | | - min::T |
328 | | - max::T |
329 | | - n::Int |
330 | | - function Extrema(T::Type = Float64) |
331 | | - a, b, S = extrema_init(T) |
332 | | - new{T,S}(a, b, 0) |
333 | | - end |
334 | | -end |
335 | | -extrema_init(T::Type{<:Number}) = typemax(T), typemin(T), Number |
336 | | -extrema_init(T::Type{String}) = "", "", String |
337 | | -extrema_init(T::Type{Date}) = typemax(Date), typemin(Date), Date |
338 | | -extrema_init(T::Type) = rand(T), rand(T), T |
339 | | -function _fit!(o::Extrema, y) |
340 | | - (o.n += 1) == 1 && (o.min = o.max = y) |
341 | | - o.min = min(o.min, y) |
342 | | - o.max = max(o.max, y) |
343 | | -end |
344 | | -function _merge!(o::Extrema, o2::Extrema) |
345 | | - o.min = min(o.min, o2.min) |
346 | | - o.max = max(o.max, o2.max) |
347 | | - o.n += o2.n |
348 | | - o |
349 | | -end |
350 | | -value(o::Extrema) = (o.min, o.max) |
351 | | -Base.extrema(o::Extrema) = value(o) |
352 | | -Base.maximum(o::Extrema) = o.max |
353 | | -Base.minimum(o::Extrema) = o.min |
354 | | - |
355 | | -#-----------------------------------------------------------------------# FTSeries |
356 | | -""" |
357 | | - FTSeries(stats...; filter=x->true, transform=identity) |
358 | | -
|
359 | | -Track multiple stats for one data stream that is filtered and transformed before being |
360 | | -fitted. |
361 | | -
|
362 | | - FTSeries(T, stats...; filter, transform) |
363 | | -
|
364 | | -Create an FTSeries and specify the type `T` of the transformed values. |
365 | | -
|
366 | | -# Example |
367 | | -
|
368 | | - o = FTSeries(Mean(), Variance(); transform=abs) |
369 | | - fit!(o, -rand(1000)) |
370 | | -
|
371 | | - # Remove missing values represented as DataValues |
372 | | - using DataValues |
373 | | - y = DataValueArray(randn(100), rand(Bool, 100)) |
374 | | - o = FTSeries(DataValue, Mean(); transform=get, filter=!isna) |
375 | | - fit!(o, y) |
376 | | -""" |
377 | | -mutable struct FTSeries{N, OS<:Tup, F, T} <: StatCollection{Union{N,Missing}} |
378 | | - stats::OS |
379 | | - filter::F |
380 | | - transform::T |
381 | | - nfiltered::Int |
382 | | -end |
383 | | -function FTSeries(stats::OnlineStat...; filter=x->true, transform=identity) |
384 | | - Ts = input.(stats) |
385 | | - FTSeries{Union{Ts...}, typeof(stats), typeof(filter), typeof(transform)}( |
386 | | - stats, filter, transform, 0 |
387 | | - ) |
388 | | -end |
389 | | -function FTSeries(T::Type, stats::OnlineStat...; filter=x->true, transform=identity) |
390 | | - FTSeries{T, typeof(stats), typeof(filter), typeof(transform)}(stats, filter, transform, 0) |
391 | | -end |
392 | | -value(o::FTSeries) = value.(o.stats) |
393 | | -nobs(o::FTSeries) = nobs(o.stats[1]) |
394 | | -@generated function _fit!(o::FTSeries{N, OS}, y) where {N, OS} |
395 | | - n = length(fieldnames(OS)) |
396 | | - quote |
397 | | - if o.filter(y) |
398 | | - yt = o.transform(y) |
399 | | - Base.Cartesian.@nexprs $n i -> @inbounds begin |
400 | | - _fit!(o.stats[i], yt) |
401 | | - end |
402 | | - else |
403 | | - o.nfiltered += 1 |
404 | | - end |
405 | | - end |
406 | | -end |
407 | | -function _merge!(o::FTSeries, o2::FTSeries) |
408 | | - o.nfiltered += o2.nfiltered |
409 | | - _merge!.(o.stats, o2.stats) |
410 | | - o |
411 | | -end |
412 | | - |
413 | 289 | #-----------------------------------------------------------------------# Group |
414 | 290 | """ |
415 | 291 | Group(stats::OnlineStat...) |
@@ -1118,57 +994,6 @@ function _merge!(o::T, o2::T) where {T<:ReservoirSample} |
1118 | 994 | end |
1119 | 995 | end |
1120 | 996 |
|
1121 | | -#-----------------------------------------------------------------------# Series |
1122 | | -""" |
1123 | | - Series(stats) |
1124 | | - Series(stats...) |
1125 | | - Series(; stats...) |
1126 | | -
|
1127 | | -Track a collection stats for one data stream. |
1128 | | -
|
1129 | | -# Example |
1130 | | -
|
1131 | | - s = Series(Mean(), Variance()) |
1132 | | - fit!(s, randn(1000)) |
1133 | | -""" |
1134 | | -struct Series{IN, T} <: StatCollection{IN} |
1135 | | - stats::T |
1136 | | - function Series(stats::T) where T |
1137 | | - IN = Union{map(input, stats)...} |
1138 | | - new{IN, T}(stats) |
1139 | | - end |
1140 | | -end |
1141 | | -Series(t::OnlineStat...) = Series(t) |
1142 | | -Series(; t...) = Series(t.data) |
1143 | | - |
1144 | | -value(o::Series) = map(value, o.stats) |
1145 | | -nobs(o::Series) = nobs(o.stats[1]) |
1146 | | -@generated function _fit!(o::Series{IN, T}, y) where {IN, T} |
1147 | | - n = length(fieldnames(T)) |
1148 | | - :(Base.Cartesian.@nexprs $n i -> _fit!(o.stats[i], y)) |
1149 | | -end |
1150 | | -_merge!(o::Series, o2::Series) = map(_merge!, o.stats, o2.stats) |
1151 | | - |
1152 | | -#-----------------------------------------------------------------------# Sum |
1153 | | -""" |
1154 | | - Sum(T::Type = Float64) |
1155 | | -
|
1156 | | -Track the overall sum. |
1157 | | -
|
1158 | | -# Example |
1159 | | -
|
1160 | | - fit!(Sum(Int), fill(1, 100)) |
1161 | | -""" |
1162 | | -mutable struct Sum{T} <: OnlineStat{Number} |
1163 | | - sum::T |
1164 | | - n::Int |
1165 | | -end |
1166 | | -Sum(T::Type = Float64) = Sum(T(0), 0) |
1167 | | -Base.sum(o::Sum) = o.sum |
1168 | | -_fit!(o::Sum{T}, x::Real) where {T<:AbstractFloat} = (o.sum += convert(T, x); o.n += 1) |
1169 | | -_fit!(o::Sum{T}, x::Real) where {T<:Integer} = (o.sum += round(T, x); o.n += 1) |
1170 | | -_merge!(o::T, o2::T) where {T <: Sum} = (o.sum += o2.sum; o.n += o2.n; o) |
1171 | | - |
1172 | 997 | # #-----------------------------------------------------------------------# Summarizer |
1173 | 998 | # mutable struct Summarizer{T} <: OnlineStat{T} |
1174 | 999 | # group::Group |
|
0 commit comments