diff --git a/NEWS.md b/NEWS.md index 86721af196..2c3133c19b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# DataFrames.jl v1.6 Release Notes + +## New functionalities + +* `Not` allows for passing multiple postiional arguments that are + treated as if they were wrapped in `Cols` + ([#3302](https://github.com/JuliaData/DataFrames.jl/pull/3302)) + # DataFrames.jl v1.5 Release Notes ## New functionalities diff --git a/Project.toml b/Project.toml index cc56cb70b2..464978361f 100644 --- a/Project.toml +++ b/Project.toml @@ -31,7 +31,7 @@ CategoricalArrays = "0.10.0" Compat = "4.2" DataAPI = "1.14.0" InlineStrings = "1.3.0" -InvertedIndices = "1" +InvertedIndices = "1.3" IteratorInterfaceExtensions = "0.1.1, 1" Missings = "0.4.2, 1" PooledArrays = "1.4.2" diff --git a/docs/src/lib/indexing.md b/docs/src/lib/indexing.md index 326b3e6d40..ed2ca488d6 100644 --- a/docs/src/lib/indexing.md +++ b/docs/src/lib/indexing.md @@ -33,6 +33,7 @@ The following values are a valid column index: * a `Not` expression (see [InvertedIndices.jl](https://github.com/JuliaData/InvertedIndices.jl)); `Not(idx)` selects all indices not in the passed `idx`; + when passed as column selector `Not(idx...)` is equivalent to `Not(Cols(idx...))`. * a `Cols` expression (see [DataAPI.jl](https://github.com/JuliaData/DataAPI.jl)); `Cols(idxs...)` selects the union of the selections in `idxs`; in particular `Cols()` diff --git a/src/other/index.jl b/src/other/index.jl index b444bbdd9a..8daadca1c6 100644 --- a/src/other/index.jl +++ b/src/other/index.jl @@ -226,6 +226,8 @@ end @inline Base.getindex(x::AbstractIndex, ::Colon) = Base.OneTo(length(x)) @inline Base.getindex(x::AbstractIndex, notidx::Not) = setdiff(1:length(x), getindex(x, notidx.skip)) +@inline Base.getindex(x::AbstractIndex, notidx::Not{InvertedIndices.NotMultiIndex}) = + setdiff(1:length(x), getindex(x, Cols(notidx.skip.indices...))) @inline Base.getindex(x::AbstractIndex, idx::Between) = x[idx.first]:x[idx.last] @inline Base.getindex(x::AbstractIndex, idx::All) = isempty(idx.cols) ? (1:length(x)) : throw(ArgumentError("All(args...) is not supported: use Cols(args...) instead")) diff --git a/test/index.jl b/test/index.jl index a9b5664fdd..a9b652b956 100644 --- a/test/index.jl +++ b/test/index.jl @@ -115,6 +115,9 @@ end si7 = SubIndex(i, Not(1:2)) si8 = SubIndex(i, ["C", "D", "E"]) si9 = SubIndex(i, Not(Not(["C", "D", "E"]))) + si10 = SubIndex(i, Not(1, 2)) + si11 = SubIndex(i, Not(:A, :B)) + si12 = SubIndex(i, Not(2, "A")) @test copy(si1) == i @test copy(si2) == Index([:C, :D, :E]) @@ -125,6 +128,9 @@ end @test copy(si7) == Index([:C, :D, :E]) @test copy(si8) == Index([:C, :D, :E]) @test copy(si9) == Index([:C, :D, :E]) + @test copy(si10) == Index([:C, :D, :E]) + @test copy(si11) == Index([:C, :D, :E]) + @test copy(si12) == Index([:C, :D, :E]) @test_throws ArgumentError SubIndex(i, 1) @test_throws ArgumentError SubIndex(i, :A) @@ -327,6 +333,8 @@ end push!(i, :x131) push!(i, :y13) push!(i, :yy13) + @test i[Not(2, 4, 5)] == [1, 3] + @test i[Not(2, :y13, "yy13")] == [1, 3] @test i[Not(Not(r"x1."))] == [2, 3] @test isempty(i[Not(Not(r"xx"))]) @test i[Not(Not(r""))] == 1:5 diff --git a/test/indexing.jl b/test/indexing.jl index 13a1890f83..7660a9601b 100644 --- a/test/indexing.jl +++ b/test/indexing.jl @@ -19,6 +19,15 @@ using Test, DataFrames, Unicode, Random @test dfx[!, 1] === df[!, names(dfx)[1]] end + @test df[!, Not(1, 2)] == DataFrame(c=7:9) + @test df[!, Not(:b, 1)] == DataFrame(c=7:9) + @test df[!, Not("c", :a)] == DataFrame(b=4:6) + @test df[!, Not(:b, "c", :a)] == DataFrame() + @test df[!, Not([1, 2], :b)] == DataFrame(c=7:9) + @test df[!, Not([:c, :a], :b)] == DataFrame() + @test df[!, Not([1, 2], 2)] == DataFrame(c=7:9) + @test df[!, Not([1, 2], [1, 2])] == DataFrame(c=7:9) + @test df[1, 1] == 1 @test df[1, 1:2] isa DataFrameRow @test df[1, r"[ab]"] isa DataFrameRow