From b5726b0bcede06facdb70f007a9f09ad6c6f594c Mon Sep 17 00:00:00 2001 From: Liza <90000517+eliza-eliza@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:48:28 +0300 Subject: [PATCH] Add `append!`, `vcat`, and `cumsum` to TimeArray (#8) --- Project.toml | 2 +- docs/src/pages/array.md | 3 ++ src/array.jl | 108 ++++++++++++++++++++++++++++++++++++++ test/array.jl | 111 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 222 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index cd41313..e814112 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "TimeArrays" uuid = "058eeebf-2231-41de-8410-62311c15f51e" -version = "1.1.1" +version = "1.2.0" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/docs/src/pages/array.md b/docs/src/pages/array.md index 00ddd54..97b7921 100644 --- a/docs/src/pages/array.md +++ b/docs/src/pages/array.md @@ -2,6 +2,9 @@ ```@docs replace +append! +vcat +cumsum ta_backward_fill ta_forward_fill ta_linear_fill diff --git a/src/array.jl b/src/array.jl index f9021c4..26aca0f 100644 --- a/src/array.jl +++ b/src/array.jl @@ -62,6 +62,114 @@ function Base.replace(f::Function, t_array::TimeArray; count = length(t_array)) return TimeArray(timestamps, replace(f, timevalues; count)) end +""" + append!(t_array::TimeArray, new_ticks::AbstractVector{TimeTick}) -> TimeArray + +Add new values from `items` to `new_ticks` and sorts them by date in ascending order. + +!!! warning + Avoid inserting data in small batches, as each call to the append method triggers sorting. + +## Examples + +```jldoctest +julia> using Dates + +julia> t_array = TimeArray([ + TimeTick(DateTime("2024-01-01"), 1.0), + TimeTick(DateTime("2024-01-02"), 2.0), + TimeTick(DateTime("2024-01-03"), 3.0), + ]); + +julia> new_ticks = [ + TimeTick(DateTime("2024-01-01"), 1.0), + TimeTick(DateTime("2024-01-02"), 2.0), + TimeTick(DateTime("2024-01-03"), 3.0), + ]; + +julia> append!(t_array, new_ticks) +6-element Vector{TimeTick{DateTime, Float64}}: + TimeTick(2024-01-01T00:00:00, 1.0) + TimeTick(2024-01-01T00:00:00, 1.0) + TimeTick(2024-01-02T00:00:00, 2.0) + TimeTick(2024-01-02T00:00:00, 2.0) + TimeTick(2024-01-03T00:00:00, 3.0) + TimeTick(2024-01-03T00:00:00, 3.0) +``` +""" +function Base.append!(t_array::TimeArray{T,V}, new_ticks::AbstractVector{TimeTick{T,V}}) where {T,V} + values = ta_values(t_array) + append!(values, new_ticks) + return TimeArray{T,V}(values) +end + +""" + vcat(l_array::TimeArray, r_array::TimeArray) -> TimeArray + +Concatenates two `TimeArray` objects vertically. + +## Examples + +```jldoctest +julia> using Dates + +julia> t_array_1 = TimeArray([ + TimeTick(DateTime("2024-01-01"), 1.0), + TimeTick(DateTime("2024-01-02"), 2.0), + TimeTick(DateTime("2024-01-03"), 3.0), + ]); + +julia> t_array_2 = TimeArray([ + TimeTick(DateTime("2024-01-04"), 1.0), + TimeTick(DateTime("2024-01-02"), 2.0), + TimeTick(DateTime("2024-01-01"), 3.0), + ]); + +julia> vcat(t_array_1, t_array_2) +6-element Vector{TimeTick{DateTime, Float64}}: + TimeTick(2024-01-01T00:00:00, 1.0) + TimeTick(2024-01-01T00:00:00, 3.0) + TimeTick(2024-01-02T00:00:00, 2.0) + TimeTick(2024-01-02T00:00:00, 2.0) + TimeTick(2024-01-03T00:00:00, 3.0) + TimeTick(2024-01-04T00:00:00, 1.0) +``` +""" +function Base.vcat(l_array::TimeArray{T1,V1}, r_array::TimeArray{T2,V2}) where {T1,V1,T2,V2} + values = vcat(ta_values(l_array), ta_values(r_array)) + return TimeArray{promote_type(T1,T2),promote_type(V1,V2)}(values) +end + +""" + cumsum(t_array::TimeArray; kw...) -> TimeArray + +Cumulative sum along the TimeTick values. + +## Examples + +```jldoctest +julia> using Dates + +julia> t_array = TimeArray([ + TimeTick(DateTime("2024-01-01"), 1.0), + TimeTick(DateTime("2024-01-02"), 2.0), + TimeTick(DateTime("2024-01-03"), 3.0), + ]); + +julia> cumsum(t_array) +6-element Vector{TimeTick{DateTime, Float64}}: + TimeTick(2024-01-01T00:00:00, 1.0) + TimeTick(2024-01-02T00:00:00, 3.0) + TimeTick(2024-01-03T00:00:00, 6.0) +``` +""" +function Base.cumsum(t_array::TimeArray{T,V}; kw...) where {T,V} + values = ta_values(t_array) + timestamps = map(ta_timestamp, values) + timevalues = map(ta_value, values) + return TimeArray(timestamps, cumsum(timevalues; kw...)) +end + """ ta_backward_fill([, pattern::Function], t_array::TimeArray) -> TimeArray diff --git a/test/array.jl b/test/array.jl index 7c90256..0bc13d3 100644 --- a/test/array.jl +++ b/test/array.jl @@ -16,7 +16,7 @@ TimeTick(Time(3), 3.0), ]), ) == a -end + end @testset "Case №2: Replacing NaN's" begin a = TimeArray([ TimeTick(Time(1), 1.0), @@ -114,4 +114,113 @@ end ta_forward_fill(isinf, ta_nan), ) end + + @testset "Case №1: Append method" begin + a = TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + ]) + + new_values = [ + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + ] + + append!(a, new_values) + + @test a == TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + TimeTick(Time(3), 1.0), + ]) + + new_values2 = [ + TimeTick(Time(3), 3.0), + TimeTick(Time(5), 5.0), + TimeTick(Time(4), 1.8), + ] + + append!(a, new_values2) + + @test a == TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + TimeTick(Time(3), 1.0), + TimeTick(Time(3), 3.0), + TimeTick(Time(4), 1.8), + TimeTick(Time(5), 5.0), + ]) + end + + @testset "Case №1: Vcat method" begin + a = TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + ]) + + b = TimeArray([ + TimeTick(Time(4), 3.0), + TimeTick(Time(5), 3.0), + TimeTick(Time(6), 3.0), + ]) + + @test vcat(a, b) == TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + TimeTick(Time(4), 3.0), + TimeTick(Time(5), 3.0), + TimeTick(Time(6), 3.0), + ]) + + c = TimeArray([ + TimeTick(Time(1), 3.0), + TimeTick(Time(3), 5.0), + TimeTick(Time(2), 1.0), + ]) + + @test vcat(a, c) == TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(1), 3.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + TimeTick(Time(3), 5.0), + ]) + end + + @testset "Case №1: Vcat method" begin + a = TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 1.0), + TimeTick(Time(3), 1.0), + ]) + + @test isequal(cumsum(a), TimeArray([ + TimeTick(Time(1), 1.0), + TimeTick(Time(2), 2.0), + TimeTick(Time(3), 3.0), + ])) + + b = TimeArray([ + TimeTick(Time(1), 3.0), + TimeTick(Time(2), NaN), + TimeTick(Time(3), 4.0), + ]) + + @test isequal(cumsum(b), TimeArray([ + TimeTick(Time(1), 3.0), + TimeTick(Time(2), NaN), + TimeTick(Time(3), NaN), + ])) + end end