542goweast
542goweast

Reputation: 192

Select elements that are not a part of an integer list in base Julia

If I have a Float64 vector Y and an integer vector x, for instance x=rand(1:1000, 500), is there an elegant way to pull the elements of Y at non-x entries? So far I have tried Y[findall([i ∉ x for i in 1:1000])]. This works, but coming from R, I was hoping to do something like Y[.!x] or Y[!x], which both throw errors. I would like to refrain from a package like DataFrames, but if this is not possible I understand.

Thanks in advance.

Upvotes: 3

Views: 202

Answers (2)

ahnlabb
ahnlabb

Reputation: 2162

Since the question explicitly asked for a solution that does not rely on packages outside of the standard library here is an alternative to Przemyslaw Szufel's solution:

Y[∉(x).(1:length(Y))]

Here we use the partially applied form of . From the documentation for in:

in(collection)
∈(collection)

Create a function that checks whether its argument is in collection, i.e. a function equivalent to y -> y in collection.

The same thing can be written in a few different ways, e.g. Y[eachindex(Y) .∉ Ref(x)] (works for this case but you should understand eachindex and have a look at LinearIndices and CartesianIndices).

An important thing to note is that these solutions do not perform well when x is large. To improve performance a Set can be created from x. Example:

Y[∉(Set(x)).(eachindex(Y))]

Upvotes: 1

Przemyslaw Szufel
Przemyslaw Szufel

Reputation: 42214

Use Not from InvertedIndices (this also gets imported with DataFrames). In your case this is Y[Not(x)], see the code below:

julia> using InvertedIndices  # or using DataFrames

julia> Y  = collect(1:0.5:4)             
7-element Vector{Float64}:               
 1.0                                     
 1.5                                     
 2.0                                     
 2.5                                     
 3.0                                     
 3.5                                     
 4.0                                     
                                         
julia> x=rand(1:7, 3)                    
3-element Vector{Int64}:                 
 3                                       
 2                                       
 6                                       
                                         
                       
julia> Y[Not(x)]                         
4-element Vector{Float64}:               
 1.0                                     
 2.5                                     
 3.0                                     
 4.0                                     

Upvotes: 4

Related Questions