-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Open
Labels
featureIndicates new feature / enhancement requestsIndicates new feature / enhancement requests
Description
Currently Base.diff(x)
produces a new vector with length length(x) - 1
.
This is often annoying when working with tabular data, since you cannot do
df.x_diff = diff(df.x)
@nalimilan recommended a keyword argument to Base.diff
, which allows for pre-pending a default value such that length, and shape more generally in the case of matrices and other arrays, is preserved.
Given the discussion in the issue below, I propose keyword arguments fillfirst
and filllast
which indicate the value appended to the array.
julia> begin
function newdiff(a::AbstractArray{T,N}; dims::Integer=1,
fillfirst=nothing,
filllast=nothing) where {T,N}
Base.require_one_based_indexing(a)
1 <= dims <= N || throw(ArgumentError("dimension $dims out of range (1:$N)"))
r = axes(a)
r0 = ntuple(i -> i == dims ? UnitRange(1, last(r[i]) - 1) : UnitRange(r[i]), N)
r1 = ntuple(i -> i == dims ? UnitRange(2, last(r[i])) : UnitRange(r[i]), N)
if fillfirst !== nothing
out = similar(a, Union{eltype(a), typeof(fillfirst)})
out .= fillfirst
out[r1...] .= view(a, r1...) .- view(a, r0...)
return out
elseif filllast !== nothing
out = similar(a, Union{eltype(a), typeof(filllast)})
out .= filllast
out[r0...] .= view(a, r1...) .- view(a, r0...)
return out
else
view(a, r0...)
return view(a, r1...) .- view(a, r0...)
end
end
end
newdiff (generic function with 1 method)
julia> x = collect(1:5) # separate method for ranges;
julia> newdiff(x)
4-element Vector{Int64}:
1
1
1
1
julia> newdiff(x; fillfirst=0)
5-element Vector{Int64}:
0
1
1
1
1
julia> newdiff(x; filllast=0)
5-element Vector{Int64}:
1
1
1
1
0
nalimilan and tomhaberKristofferC
Metadata
Metadata
Assignees
Labels
featureIndicates new feature / enhancement requestsIndicates new feature / enhancement requests