检查数组 Julia 中单调性的有效方法?
Efficient method for checking monotonicity in array Julia?
试图想出一种快速的方法来确保 a 在 Julia 中是单调的。
我一直使用的缓慢(且明显)的方法是这样的:
function check_monotonicity(
timeseries::Array,
column::Int
)
current = timeseries[1,column]
for row in 1:size(timeseries, 1)
if timeseries[row,column] > current
return false
end
current = copy(timeseries[row,column])
end
return true
end
所以它的工作原理是这样的:
julia> using Distributions
julia>mono_matrix = hcat(collect(0:0.1:10), rand(Uniform(0.4,0.6),101),reverse(collect(0.0:0.1:10.0)))
101×3 Matrix{Float64}:
0.0 0.574138 10.0
0.1 0.490671 9.9
0.2 0.457519 9.8
0.3 0.567687 9.7
⋮
9.8 0.513691 0.2
9.9 0.589585 0.1
10.0 0.405018 0.0
julia> check_monotonicity(mono_matrix, 2)
false
然后是相反的例子:
julia> check_monotonicity(mono_matrix, 3)
true
有谁知道对长时间序列执行此操作的更有效方法吗?
在数学中,通常我们将一个级数定义为单调的,如果它是 non-decreasing 或 non-increasing。如果这是你想要的,那么做:
issorted(view(mono_matrix, :, 2), rev=true)
检查是否为non-increasing,并且:
issorted(view(mono_matrix, :, 2))
检查它是否是 non-decreasing。
如果你想要递减支票:
issorted(view(mono_matrix, :, 3), rev=true, lt = <=)
用于减少,但将 0.0
和 -0.0
视为相等或
issorted(view(mono_matrix, :, 3), lt = <=)
用于增加,但将 0.0
和 -0.0
视为相等。
如果要区分0.0
和-0.0
则分别做:
issorted(view(mono_matrix, :, 3), rev=true, lt = (x, y) -> isequal(x, y) || isless(x, y))
issorted(view(mono_matrix, :, 3), lt = (x, y) -> isequal(x, y) || isless(x, y))
你的实现肯定不慢!它几乎是最佳速度。你绝对应该去掉 copy
。虽然当矩阵元素只是普通数据时它不会受到伤害,但在其他情况下可能会很糟糕,例如 BigInt
。
这与您最初的成果很接近,但在索引和数组类型方面也更稳健:
function ismonotonic(A::AbstractMatrix, column::Int, cmp = <)
current = A[begin, column] # begin instead of 1
for i in axes(A, 1)[2:end] # skip the first element
newval = A[i, column] # don't use copy here
cmp(newval, current) && return false
current = newval
end
return true
end
另一个提示:您不需要使用 collect
。事实上,您几乎 永远不会 使用 collect。改为这样做(我删除了 Uniform
,因为我没有 Distributions.jl):
mono_matrix = hcat(0:0.1:10, rand(101), reverse(0:0.1:10)) # or 10:-0.1:0
或者这样更好,因为您可以更好地控制范围内的元素数量:
mono_matrix = hcat(range(0, 10, 101), rand(101), range(10, 0, 101))
那么你可以这样使用它:
1.7.2> ismonotonic(mono_matrix, 3)
false
1.7.2> ismonotonic(mono_matrix, 3, >=)
true
1.7.2> ismonotonic(mono_matrix, 1)
true
试图想出一种快速的方法来确保 a 在 Julia 中是单调的。
我一直使用的缓慢(且明显)的方法是这样的:
function check_monotonicity(
timeseries::Array,
column::Int
)
current = timeseries[1,column]
for row in 1:size(timeseries, 1)
if timeseries[row,column] > current
return false
end
current = copy(timeseries[row,column])
end
return true
end
所以它的工作原理是这样的:
julia> using Distributions
julia>mono_matrix = hcat(collect(0:0.1:10), rand(Uniform(0.4,0.6),101),reverse(collect(0.0:0.1:10.0)))
101×3 Matrix{Float64}:
0.0 0.574138 10.0
0.1 0.490671 9.9
0.2 0.457519 9.8
0.3 0.567687 9.7
⋮
9.8 0.513691 0.2
9.9 0.589585 0.1
10.0 0.405018 0.0
julia> check_monotonicity(mono_matrix, 2)
false
然后是相反的例子:
julia> check_monotonicity(mono_matrix, 3)
true
有谁知道对长时间序列执行此操作的更有效方法吗?
在数学中,通常我们将一个级数定义为单调的,如果它是 non-decreasing 或 non-increasing。如果这是你想要的,那么做:
issorted(view(mono_matrix, :, 2), rev=true)
检查是否为non-increasing,并且:
issorted(view(mono_matrix, :, 2))
检查它是否是 non-decreasing。
如果你想要递减支票:
issorted(view(mono_matrix, :, 3), rev=true, lt = <=)
用于减少,但将 0.0
和 -0.0
视为相等或
issorted(view(mono_matrix, :, 3), lt = <=)
用于增加,但将 0.0
和 -0.0
视为相等。
如果要区分0.0
和-0.0
则分别做:
issorted(view(mono_matrix, :, 3), rev=true, lt = (x, y) -> isequal(x, y) || isless(x, y))
issorted(view(mono_matrix, :, 3), lt = (x, y) -> isequal(x, y) || isless(x, y))
你的实现肯定不慢!它几乎是最佳速度。你绝对应该去掉 copy
。虽然当矩阵元素只是普通数据时它不会受到伤害,但在其他情况下可能会很糟糕,例如 BigInt
。
这与您最初的成果很接近,但在索引和数组类型方面也更稳健:
function ismonotonic(A::AbstractMatrix, column::Int, cmp = <)
current = A[begin, column] # begin instead of 1
for i in axes(A, 1)[2:end] # skip the first element
newval = A[i, column] # don't use copy here
cmp(newval, current) && return false
current = newval
end
return true
end
另一个提示:您不需要使用 collect
。事实上,您几乎 永远不会 使用 collect。改为这样做(我删除了 Uniform
,因为我没有 Distributions.jl):
mono_matrix = hcat(0:0.1:10, rand(101), reverse(0:0.1:10)) # or 10:-0.1:0
或者这样更好,因为您可以更好地控制范围内的元素数量:
mono_matrix = hcat(range(0, 10, 101), rand(101), range(10, 0, 101))
那么你可以这样使用它:
1.7.2> ismonotonic(mono_matrix, 3)
false
1.7.2> ismonotonic(mono_matrix, 3, >=)
true
1.7.2> ismonotonic(mono_matrix, 1)
true