In R, you can index all elements except for the second, by negative indexing: myvector[-2]. This is especially usefull if you want to make two complete subsets of a vector:
set1 = myvector[inds]
set2 = myvector[-inds]
What do you find to be the best way of implementing “negative indexing”?
Thanks for the reference! It is nice that this problem is already solved by a package. However, I feel that adding a package dependency seems a bit much for such a simple task, especially if it is only needed a single time.
The following example uses the Base function setdiff, which I found to be an improvement on my initial attempt:
For what it’s worth, InvertedIndices.jl only defines and exports the InvertedIndex type (also aliased as Not) and itself has no dependencies. I generally consider small self-contained packages like this as not actually being dependencies because they don’t really slow down precompilation or importing and there is no chance that they will break compatibility with other packages.
Well it’s technically a (fast to load) dependency:
julia> @time using InvertedIndices
0.019317 seconds (5.43 k allocations: 422.184 KiB, 54.67% compilation time)
While needing it may not be too common, I wander if it or something similar should be a Julia stdlib. Mostly for discovery. and, or and I think not have been suggested for Julia 2.0 (as aliases, or by me with slightly different semantics).
I’m not sure upper-cased Not is already claimed by some other package, also seems like a bad variable name…
If this where to be merged into Julia, then better sooner rather than later? The API could be the same, but clearly the speed could be improved. If not considered, put a link to it in the official docs, mention in
in the following function I tried to make the most of the info that inds is sorted.
Apart from the use of specific information what else can be done to improve the execution time?
function dat(v,idx)
mid=Int[]
pre=@view v[1:inds[1]-1]
post=@view v[inds[end]+1:end]
shinds=inds[2:end-1] .-inds[1]
@inbounds for (i,e) in enumerate(v[inds[1]+1:inds[end]-1])
if i ∉ shinds
push!(mid,e)
end
end
[pre; mid; post]
end
A performant and really flexible solution is to use Accessors.jl: @delete A[123] returns a copy of A without element at index 123.
It has the same performance as manual selection:
Sorry, I didn’t read in enough details first, and only noticed the myvector[-2] example with a single index. Indeed, @delete only works for a single index now, saying as an author of its implementation (: Basically, I only needed single indices myself, and didn’t even think of more general cases here. The implementation is extremely simple though: https://github.com/JuliaObjects/Accessors.jl/blob/master/src/optics.jl#L412-L415, and I think extension PRs would be welcome.
julia> function f(x,inds)
y = Vector{eltype(x)}(undef,length(x) - length(inds))
j = 0
for i in Iterators.filter(!in(inds),eachindex(x))
j += 1
@inbounds y[j] = x[i]
end
return y
end
f (generic function with 1 method)
julia> x = collect(1:10); inds = [3,5,6];
julia> @btime f($x,$inds)
72.919 ns (1 allocation: 112 bytes)
7-element Vector{Int64}:
1
2
4
7
8
9
10
Modifying the original array:
julia> function f!(x,inds)
for i in Iterators.reverse(Iterators.filter(in(inds),eachindex(x)))
deleteat!(x,i)
end
return x
end
f! (generic function with 1 method)
julia> @btime f!(x,$inds) setup=(x=copy($x)) evals=1
121.000 ns (0 allocations: 0 bytes)
7-element Vector{Int64}:
1
2
4
7
8
9
10
While I’ve probably seen your package mentioned before, I would have never thought of looking at it for exclusive indexing. Nor from just a quick look at the README now. But it’s good to know of all these alternative ways to do this, hopefully we’ll get at a best way, for more than one index AND at the same time best syntax and something viable to merge into Julia.
The criteria to include in Julia is that it’s helpful for Julia itself. Well, I don’t see it off-hand how relevant it is… seems they can do without (or not?). At least I would like to know the full syntax of the most important competitors, R, Python, and MATLAB, and how they map to Julia in once place.
Please help with Julia’s (unofficial) wikibook and/or PR to Julia’s docs. I’m not sure how wanted it is to list every difference in the official docs. The former is also good to know of and maintain, easier to do than the official docs:
the following function also manages index arrays and has intermediate times with respect to those of the two functions above
function delat(v,idx)
mid=eltype(v)[]
shinds=idx[1:end] .-idx[1].+1
l=idx[1]
r=idx[end]
@inbounds for (i,e) in enumerate(v[l:r])
if i ∉ shinds
push!(mid,e)
end
end
[@view v[1:idx[1]-1]; mid; @view v[idx[end]+1:end]]
end