Skip to content

Commit efe6e91

Browse files
authored
Add Satisfies transform and derived transforms: Only and Except (#236)
* Add 'Satisfies' transform and derived transforms: 'Only' and 'Except' * Update docstrings * Fix typo
1 parent 363db49 commit efe6e91

File tree

9 files changed

+162
-72
lines changed

9 files changed

+162
-72
lines changed

docs/src/transforms.md

+12
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,24 @@ Select
1414
Reject
1515
```
1616

17+
## Satisfies
18+
19+
```@docs
20+
Satisfies
21+
```
22+
1723
## Only
1824

1925
```@docs
2026
Only
2127
```
2228

29+
## Except
30+
31+
```@docs
32+
Except
33+
```
34+
2335
## Rename
2436

2537
```@docs

src/TableTransforms.jl

+2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ export
5151
# built-in
5252
Select,
5353
Reject,
54+
Satisfies,
5455
Only,
56+
Except,
5557
Rename,
5658
StdNames,
5759
Sort,

src/transforms.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ end
265265
# ----------------
266266

267267
include("transforms/select.jl")
268-
include("transforms/only.jl")
268+
include("transforms/satisfies.jl")
269269
include("transforms/rename.jl")
270270
include("transforms/stdnames.jl")
271271
include("transforms/sort.jl")

src/transforms/only.jl

-40
This file was deleted.

src/transforms/satisfies.jl

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# ------------------------------------------------------------------
2+
# Licensed under the MIT License. See LICENSE in the project root.
3+
# ------------------------------------------------------------------
4+
5+
"""
6+
Satisfies(pred)
7+
8+
Selects the columns where `pred(column)` returns `true`.
9+
10+
# Examples
11+
12+
```julia
13+
Satisfies(allunique)
14+
Satisfies(x -> sum(x) > 100)
15+
Satisfies(x -> eltype(x) <: Integer)
16+
```
17+
"""
18+
struct Satisfies{F} <: StatelessFeatureTransform
19+
pred::F
20+
end
21+
22+
isrevertible(::Type{<:Satisfies}) = true
23+
24+
function applyfeat(transform::Satisfies, feat, prep)
25+
pred = transform.pred
26+
cols = Tables.columns(feat)
27+
names = Tables.columnnames(cols)
28+
snames = filter(names) do name
29+
x = Tables.getcolumn(cols, name)
30+
pred(x)
31+
end
32+
strans = Select(snames)
33+
newfeat, sfcache = applyfeat(strans, feat, prep)
34+
newfeat, (strans, sfcache)
35+
end
36+
37+
function revertfeat(::Satisfies, newfeat, fcache)
38+
strans, sfcache = fcache
39+
revertfeat(strans, newfeat, sfcache)
40+
end
41+
42+
"""
43+
Only(S)
44+
45+
Selects the columns that have scientific type `S`.
46+
47+
# Examples
48+
49+
```julia
50+
import DataScienceTraits as DST
51+
Only(DST.Continuous)
52+
```
53+
"""
54+
Only(S::Type{<:SciType}) = Satisfies(x -> elscitype(x) <: S)
55+
56+
"""
57+
Except(S)
58+
59+
Selects the columns that don't have scientific type `S`.
60+
61+
# Examples
62+
63+
```julia
64+
import DataScienceTraits as DST
65+
Except(DST.Continuous)
66+
```
67+
"""
68+
Except(S::Type{<:SciType}) = Satisfies(x -> !(elscitype(x) <: S))

test/shows.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@
4242
└─ selector = [:a, :b, :c]"""
4343
end
4444

45-
@testset "Only" begin
46-
T = Only(DST.Continuous)
45+
@testset "Satisfies" begin
46+
T = Satisfies(allunique)
4747

4848
# compact mode
4949
iostr = sprint(show, T)
50-
@test iostr == "Only(DataScienceTraits.Continuous)"
50+
@test iostr == "Satisfies(allunique)"
5151

5252
# full mode
5353
iostr = sprint(show, MIME("text/plain"), T)
5454
@test iostr == """
55-
Only transform
56-
└─ scitype = DataScienceTraits.Continuous"""
55+
Satisfies transform
56+
└─ pred = allunique"""
5757
end
5858

5959
@testset "Rename" begin

test/transforms.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
transformfiles = [
22
"select.jl",
33
"rename.jl",
4-
"only.jl",
4+
"satisfies.jl",
55
"stdnames.jl",
66
"sort.jl",
77
"sample.jl",

test/transforms/only.jl

-25
This file was deleted.

test/transforms/satisfies.jl

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
@testset "Satisfies" begin
2+
@test isrevertible(Satisfies(allunique))
3+
4+
a = [1, 2, 3, 4, 5, 6]
5+
b = [6, 5, 4, 3, 2, 1]
6+
c = [1, 2, 3, 4, 6, 6]
7+
d = [6, 6, 4, 3, 2, 1]
8+
t = Table(; a, b, c, d)
9+
10+
T = Satisfies(allunique)
11+
n, c = apply(T, t)
12+
@test Tables.schema(n).names == (:a, :b)
13+
@test Tables.getcolumn(n, :a) == t.a
14+
@test Tables.getcolumn(n, :b) == t.b
15+
tₒ = revert(T, n, c)
16+
@test t == tₒ
17+
18+
T = Satisfies(x -> sum(x) > 21)
19+
n, c = apply(T, t)
20+
@test Tables.schema(n).names == (:c, :d)
21+
@test Tables.getcolumn(n, :c) == t.c
22+
@test Tables.getcolumn(n, :d) == t.d
23+
tₒ = revert(T, n, c)
24+
@test t == tₒ
25+
end
26+
27+
@testset "Only" begin
28+
a = rand(10)
29+
b = rand(Float32, 10)
30+
c = rand(1:9, 10)
31+
d = rand('a':'z', 10)
32+
t = Table(; a, b, c, d)
33+
34+
T = Only(DST.Continuous)
35+
n, c = apply(T, t)
36+
@test Tables.schema(n).names == (:a, :b)
37+
@test Tables.getcolumn(n, :a) == t.a
38+
@test Tables.getcolumn(n, :b) == t.b
39+
tₒ = revert(T, n, c)
40+
@test t == tₒ
41+
42+
T = Only(DST.Categorical)
43+
n, c = apply(T, t)
44+
@test Tables.schema(n).names == (:c, :d)
45+
@test Tables.getcolumn(n, :c) == t.c
46+
@test Tables.getcolumn(n, :d) == t.d
47+
tₒ = revert(T, n, c)
48+
@test t == tₒ
49+
end
50+
51+
@testset "Except" begin
52+
a = rand(10)
53+
b = rand(Float32, 10)
54+
c = rand(1:9, 10)
55+
d = rand('a':'z', 10)
56+
t = Table(; a, b, c, d)
57+
58+
T = Except(DST.Categorical)
59+
n, c = apply(T, t)
60+
@test Tables.schema(n).names == (:a, :b)
61+
@test Tables.getcolumn(n, :a) == t.a
62+
@test Tables.getcolumn(n, :b) == t.b
63+
tₒ = revert(T, n, c)
64+
@test t == tₒ
65+
66+
T = Except(DST.Continuous)
67+
n, c = apply(T, t)
68+
@test Tables.schema(n).names == (:c, :d)
69+
@test Tables.getcolumn(n, :c) == t.c
70+
@test Tables.getcolumn(n, :d) == t.d
71+
tₒ = revert(T, n, c)
72+
@test t == tₒ
73+
end

0 commit comments

Comments
 (0)