0
votes

I want to figure out where is the duplicate data which cause this error, but how?

using DataFrames, TimeSeries, CSV
s = "2019-12-25,3
       2020-01-01,6
       2019-12-25,9
       2020-01-02,10
       2020-01-03,11
       2020-01-04,12
       2020-01-02,13
       2020-01-02,14"
df=CSV.read(IOBuffer(s), types=[Date,Int], header=["timestamp","V")
ta = TimeArray(df, timestamp=:timestamp)

error message

ERROR: ArgumentError: timestamps must be strictly monotonic
Stacktrace:
 [1] (::TimeSeries.var"#_#1#2")(::Bool, ::Type{TimeArray{Int64,1,Date,Array{Int64,1}}}, ::Array{Date,1}, ::Array{Int64,1}, ::Array{Symbol,1}, ::DataFrame) at /home/dlin/.julia/packages/TimeSeries/8Z5Is/src/timearray.jl:81
 [2] TimeArray at /home/dlin/.julia/packages/TimeSeries/8Z5Is/src/timearray.jl:65 [inlined]
 [3] #TimeArray#3 at /home/dlin/.julia/packages/TimeSeries/8Z5Is/src/timearray.jl:89 [inlined]
 [4] TimeArray(::Array{Date,1}, ::Array{Int64,1}, ::Array{Symbol,1}, ::DataFrame) at /home/dlin/.julia/packages/TimeSeries/8Z5Is/src/timearray.jl:89
 [5] #TimeArray#3(::Symbol, ::Type{TimeArray}, ::DataFrame) at /home/dlin/.julia/packages/TimeSeries/8Z5Is/src/tables.jl:70
 [6] (::Core.var"#kw#Type")(::NamedTuple{(:timestamp,),Tuple{Symbol}}, ::Type{TimeArray}, ::DataFrame) at ./none:0
 [7] top-level scope at REPL[239]:1

I want to find out which index caused the error, may similar to

│ Row │ timestamp  │ V     │
│     │ Date       │ Int64 │
├─────┼────────────┼───────┤
│ 1   │ 2019-12-25 │ 3     │
│ 3   │ 2019-12-25 │ 9     │

Or even better find out all non unique value rows

│ Row │ timestamp  │ V     │
│     │ Date       │ Int64 │
├─────┼────────────┼───────┤
│ 1   │ 2019-12-25 │ 3     │
│ 3   │ 2019-12-25 │ 9     │
│ 4   │ 2020-01-02 │ 10    │
│ 7   │ 2020-01-02 │ 13    │
│ 8   │ 2020-01-02 │ 14    │
2
Your title mentions a TimeSeries with a monotonicity error while your post mentions a TimeArray with a keyword error. Can you edit your post to clarify? - nanofarad

2 Answers

1
votes

Remove duplicates and than pass DataFrame to TimeArray:

julia> TimeArray(aggregate(df, :timestamp, minimum, sort=true), timestamp=:timestamp)
2×1 TimeArray{Int64,1,Date,Array{Int64,1}} 2019-12-25 to 2020-01-01
│            │ V_minimum │
├────────────┼───────────┤
│ 2019-12-25 │ 3         │
│ 2020-01-01 │ 6         │

If you have a DataFrame and just want to identify duplicate date values use the nonunique function.

julia> nonunique(df,:timestamp)
3-element Array{Bool,1}:
 0
 0
 1

If you want just the rows unique to the date:

julia> unique(df,:timestamp)
2×2 DataFrame
│ Row │ timestamp  │ V     │
│     │ Date       │ Int64 │
├─────┼────────────┼───────┤
│ 1   │ 2019-12-25 │ 3     │
│ 2   │ 2020-01-01 │ 6     │
0
votes

By @Przemyslaw Szufel's answer, I figure out the way to find the content, but it is still not perfect, it can't show the original row index and only show the first non unique content.

julia> v=nonunique(df,1)
8-element Array{Bool,1}:
 0
 0
 1
 0
 0
 0
 1
 1

julia> f=findfirst(v)
3
julia> df[df.Column1 .== df.Column1[f],:]
2×2 DataFrame
│ Row │ Column1    │ Column2 │
│     │ Date       │ Int64   │
├─────┼────────────┼─────────┤
│ 1   │ 2019-12-25 │ 3       │
│ 2   │ 2019-12-25 │ 9       │

BTW, I found the "ArgumentError: timestamps must be strictly monotonic" message is not only monotonic, but also "sorted" after check the source code of timearray.jl.