From 231e513fe535b4df4e788946d99338e2cceafeb3 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Tue, 26 Jan 2021 23:13:49 +0000 Subject: [PATCH 01/17] Set up Transform API --- Project.toml | 4 +++ src/Transform.jl | 9 ++++++- src/transformers.jl | 66 +++++++++++++++++++++++++++++++++++++++++++++ src/utils.jl | 9 +++++++ test/runtests.jl | 2 +- 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/transformers.jl create mode 100644 src/utils.jl diff --git a/Project.toml b/Project.toml index ceb1bd5..9d645ee 100644 --- a/Project.toml +++ b/Project.toml @@ -3,7 +3,11 @@ uuid = "8fd68953-04b8-4117-ac19-158bf6de9782" authors = ["Invenia Technical Computing Corporation"] version = "0.1.0" +[deps] +Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" + [compat] +Tables = "1.3" julia = "1" [extras] diff --git a/src/Transform.jl b/src/Transform.jl index 237eea3..ae90c3a 100644 --- a/src/Transform.jl +++ b/src/Transform.jl @@ -1,5 +1,12 @@ module Transform -# Write your package code here. +using Tables + +export Transformation, Power +export transform, transform! + +include("utils.jl") +include("transformers.jl") +include("power.jl") end diff --git a/src/transformers.jl b/src/transformers.jl new file mode 100644 index 0000000..9bb6c62 --- /dev/null +++ b/src/transformers.jl @@ -0,0 +1,66 @@ + +""" + Transformation + +Abstract supertype for all transformations. +""" +abstract type Transformation end + +# Make Transforms callable types +(t::Transformation)(x; kwargs...) = transform(x, t; kwargs...) + +""" + transform!(data::T, transformation::Transformation; kwargs...) -> T + +Apply `transformation` to the `data` in-place. +Where possible, this should be extended for new data types `T`. +""" +function transform! end + +""" + transform(data::T, transformation::Transformation; kwargs...) -> T + +Non-in-place version of [`transform!`](@ref), which it delegates to by default. +Does not need to be extended unless in-place transformation is not possible. +""" +function transform end + +""" + transform!(A::AbstractArray{T}, ::Transformation; dims=:, kwargs...) where T <: Real + +Applies the transformation to each element of `A`. +Optionally specify the `dims` to apply the transformation along certain dimensions. +""" +function transform!( + A::AbstractArray{T}, t::Transformation; dims=:, kwargs... +) where T <: Real + dims == Colon() && return _transform!(A, t; kwargs...) + + return map(eachslice(A; dims=dims)) do x + return _transform!(x, t; kwargs...) + end +end + +transform(x, t::Transformation; kwargs...) = transform!(_trycopy(x), t; kwargs...) + +""" + transform!(table::T, ::Transformation; cols=nothing)::T where T + +Applies the transformation to each of the specified columns in the `table`. +If no `cols` are specified, then the transformation is applied to all columns. +""" +function transform!(table::T, t::Transformation; cols=nothing)::T where T + # TODO: We could probably handle iterators of tables here + Tables.istable(table) || throw(MethodError(transform!, (table, t))) + + # Extract a columns iterator that we should be able to use to mutate the data. + # NOTE: Mutation is not guaranteed for all table types, but it avoid copying the data + columntable = Tables.columns(table) + + cnames = cols === nothing ? propertynames(columntable) : cols + for cname in cnames + transform!(getproperty(columntable, cname), t) + end + + return table +end diff --git a/src/utils.jl b/src/utils.jl new file mode 100644 index 0000000..0c96997 --- /dev/null +++ b/src/utils.jl @@ -0,0 +1,9 @@ +function _trycopy(data) + # Not all objects support `copy`, but we should use it to improve + # performance if possible. + try + copy(data) + catch + deepcopy(data) + end +end diff --git a/test/runtests.jl b/test/runtests.jl index b6f365d..a1725a0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,5 +2,5 @@ using Transform using Test @testset "Transform.jl" begin - # Write your tests here. + include("power.jl") end From 8e5687a0315f29f3ea0c86812cd9270553c9fea7 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Tue, 26 Jan 2021 23:14:06 +0000 Subject: [PATCH 02/17] Add Power transformation --- src/power.jl | 12 ++++++++++++ test/power.jl | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/power.jl create mode 100644 test/power.jl diff --git a/src/power.jl b/src/power.jl new file mode 100644 index 0000000..e5f95e0 --- /dev/null +++ b/src/power.jl @@ -0,0 +1,12 @@ +""" + Power(exponent) <: Transformation + +Raise the data by the given `exponent`. +""" +struct Power <: Transformation + exponent::Real +end + +function _transform!(x::AbstractArray{T}, P::Power; kwargs...) where T <: Real + x[:] = x.^ P.exponent +end diff --git a/test/power.jl b/test/power.jl new file mode 100644 index 0000000..17b822c --- /dev/null +++ b/test/power.jl @@ -0,0 +1,42 @@ +@testset "power" begin + + p = Power(3) + @test p isa Transformation + + @testset "vector of reals" begin + x = [1, 2, 3, 4, 5] + expected = [1, 8, 27, 64, 125] + + @test transform(x, p) == expected + @test p(x) == expected + + _x = copy(x) + transform!(_x, p) + @test _x == expected + end + + @testset "matrix of reals" begin + M = [1 2 3; 4 5 6] + expected = [1 8 27; 64 125 216] + + @test transform(M, p) == expected + @test p(M) == expected + + _M = copy(M) + transform!(_M, p) + @test _M == expected + end + + @testset "NamedTuple of reals" begin + nt = (a = [1, 2, 3], b = [4, 5, 6]) + expected = (a = [1, 8, 27], b = [64, 125, 216]) + + @test transform(nt, p) == expected + @test p(nt) == expected + + _nt = deepcopy(nt) + transform!(_nt, p) + @test _nt == expected + end + +end From 89f8722421b6d612babd1881641eb773ac6f08de Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Thu, 28 Jan 2021 14:23:47 +0000 Subject: [PATCH 03/17] Change in-place to mutating --- src/transformers.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transformers.jl b/src/transformers.jl index 9bb6c62..93077ea 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -12,7 +12,7 @@ abstract type Transformation end """ transform!(data::T, transformation::Transformation; kwargs...) -> T -Apply `transformation` to the `data` in-place. +Apply the`transformation` mutating the input `data`. Where possible, this should be extended for new data types `T`. """ function transform! end @@ -20,8 +20,8 @@ function transform! end """ transform(data::T, transformation::Transformation; kwargs...) -> T -Non-in-place version of [`transform!`](@ref), which it delegates to by default. -Does not need to be extended unless in-place transformation is not possible. +Non-mutating version of [`transform!`](@ref), which it delegates to by default. +Does not need to be extended unless a mutating transformation is not possible. """ function transform end From 279ff663833f06334bd73066486bbfdd90773962 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Thu, 28 Jan 2021 14:25:28 +0000 Subject: [PATCH 04/17] Change _trycopy to _try_copy --- src/transformers.jl | 2 +- src/utils.jl | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/transformers.jl b/src/transformers.jl index 93077ea..ace19ad 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -41,7 +41,7 @@ function transform!( end end -transform(x, t::Transformation; kwargs...) = transform!(_trycopy(x), t; kwargs...) +transform(x, t::Transformation; kwargs...) = transform!(_try_copy(x), t; kwargs...) """ transform!(table::T, ::Transformation; cols=nothing)::T where T diff --git a/src/utils.jl b/src/utils.jl index 0c96997..f908013 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,6 +1,10 @@ -function _trycopy(data) - # Not all objects support `copy`, but we should use it to improve - # performance if possible. +""" + _try_copy(data) + +Try to `copy` the data, fallback to `deepcopy` if not supported. +Not all objects support `copy`, but we should use it to improve performance if possible. +""" +function _try_copy(data) try copy(data) catch From aeffbae81a508db7985cdff3c381909a03f9e9d0 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Thu, 28 Jan 2021 15:28:13 +0000 Subject: [PATCH 05/17] Test on all dims and columns --- src/transformers.jl | 6 ++++-- test/power.jl | 37 +++++++++++++++++++++++++++---------- test/runtests.jl | 1 + 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/transformers.jl b/src/transformers.jl index ace19ad..bf4619d 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -36,9 +36,11 @@ function transform!( ) where T <: Real dims == Colon() && return _transform!(A, t; kwargs...) - return map(eachslice(A; dims=dims)) do x - return _transform!(x, t; kwargs...) + for x in eachslice(A; dims=dims) + _transform!(x, t; kwargs...) end + + return A end transform(x, t::Transformation; kwargs...) = transform!(_try_copy(x), t; kwargs...) diff --git a/test/power.jl b/test/power.jl index 17b822c..cea82ba 100644 --- a/test/power.jl +++ b/test/power.jl @@ -19,24 +19,41 @@ M = [1 2 3; 4 5 6] expected = [1 8 27; 64 125 216] - @test transform(M, p) == expected - @test p(M) == expected + @testset "dims = $d" for d in (Colon(), 1, 2) - _M = copy(M) - transform!(_M, p) - @test _M == expected + @test transform(M, p; dims=d) == expected + @test p(M; dims=d) == expected + + _M = copy(M) + transform!(_M, p; dims=d) + @test _M == expected + end end @testset "NamedTuple of reals" begin nt = (a = [1, 2, 3], b = [4, 5, 6]) expected = (a = [1, 8, 27], b = [64, 125, 216]) - @test transform(nt, p) == expected - @test p(nt) == expected + @testset "all cols" begin + @test transform(nt, p) == expected + @test p(nt) == expected + + _nt = deepcopy(nt) + transform!(_nt, p) + @test _nt == expected + end + + @testset "cols = $c" for c in (:a, :b) + nt_mutated = NamedTuple{(Symbol("$c"), )}((expected[c], )) + nt_expected = merge(nt, nt_mutated) + + @test transform(nt, p; cols=[c]) == nt_expected + @test p(nt; cols=[c]) == nt_expected - _nt = deepcopy(nt) - transform!(_nt, p) - @test _nt == expected + _nt = deepcopy(nt) + transform!(_nt, p; cols=[c]) + @test _nt == nt_expected + end end end diff --git a/test/runtests.jl b/test/runtests.jl index a1725a0..55e9d46 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,5 @@ using Transform +using Transform: _try_copy using Test @testset "Transform.jl" begin From 1b88d63cd47bc5db5015f9e4d5fcce742061cac5 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Thu, 28 Jan 2021 15:37:59 +0000 Subject: [PATCH 06/17] Change testset names to integers --- test/power.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/power.jl b/test/power.jl index cea82ba..73a2b7b 100644 --- a/test/power.jl +++ b/test/power.jl @@ -3,7 +3,7 @@ p = Power(3) @test p isa Transformation - @testset "vector of reals" begin + @testset "vector of integers" begin x = [1, 2, 3, 4, 5] expected = [1, 8, 27, 64, 125] @@ -15,7 +15,7 @@ @test _x == expected end - @testset "matrix of reals" begin + @testset "matrix of integers" begin M = [1 2 3; 4 5 6] expected = [1 8 27; 64 125 216] @@ -30,7 +30,7 @@ end end - @testset "NamedTuple of reals" begin + @testset "NamedTuple of integers" begin nt = (a = [1, 2, 3], b = [4, 5, 6]) expected = (a = [1, 8, 27], b = [64, 125, 216]) From 9c18ab698f5a2ddaf52aa70a69bfcf7b01268582 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Thu, 28 Jan 2021 18:53:56 +0000 Subject: [PATCH 07/17] Test on AxisKeys, AxisArrays, DataFrames --- Project.toml | 8 +++++++- src/power.jl | 3 ++- test/power.jl | 44 ++++++++++++++++++++++++++++++++++++++++---- test/runtests.jl | 3 +++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/Project.toml b/Project.toml index 9d645ee..8595ab9 100644 --- a/Project.toml +++ b/Project.toml @@ -7,11 +7,17 @@ version = "0.1.0" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" [compat] +AxisArrays = "0.4" +AxisKeys = "0.1" +DataFrames = "0.22" Tables = "1.3" julia = "1" [extras] +AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["AxisArrays", "AxisKeys", "DataFrames", "Test"] diff --git a/src/power.jl b/src/power.jl index e5f95e0..af58a21 100644 --- a/src/power.jl +++ b/src/power.jl @@ -8,5 +8,6 @@ struct Power <: Transformation end function _transform!(x::AbstractArray{T}, P::Power; kwargs...) where T <: Real - x[:] = x.^ P.exponent + x[:] = x .^ P.exponent + return x end diff --git a/test/power.jl b/test/power.jl index 73a2b7b..6a2156e 100644 --- a/test/power.jl +++ b/test/power.jl @@ -3,7 +3,8 @@ p = Power(3) @test p isa Transformation - @testset "vector of integers" begin + # TODO: all of these should be part of some test utils + @testset "Vector" begin x = [1, 2, 3, 4, 5] expected = [1, 8, 27, 64, 125] @@ -15,12 +16,11 @@ @test _x == expected end - @testset "matrix of integers" begin + @testset "Matrix" begin M = [1 2 3; 4 5 6] expected = [1 8 27; 64 125 216] @testset "dims = $d" for d in (Colon(), 1, 2) - @test transform(M, p; dims=d) == expected @test p(M; dims=d) == expected @@ -30,7 +30,7 @@ end end - @testset "NamedTuple of integers" begin + @testset "NamedTuple" begin nt = (a = [1, 2, 3], b = [4, 5, 6]) expected = (a = [1, 8, 27], b = [64, 125, 216]) @@ -56,4 +56,40 @@ end end + @testset "AxisArray" begin + A = AxisArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]) + expected = AxisArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) + + @testset "dims = $d" for d in (Colon(), 1, 2) + @test transform(A, p; dims=d) == expected + end + + end + + @testset "AxisKey" begin + A = KeyedArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]) + expected = AxisArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) + + @testset "dims = $d" for d in (Colon(), :foo, :bar) + @test transform(A, p; dims=d) == expected + end + + _A = copy(A) + transform!(_A, p) + @test _A == expected + end + + @testset "DataFrame" begin + df = DataFrame(:a => [1, 2, 3], :b => [4, 5, 6]) + expected = DataFrame(:a => [1, 8, 27], :b => [64, 125, 216]) + + @test transform(df, p) == expected + @test transform(df, p; cols=[:a]) == DataFrame(:a => [1, 8, 27], :b => [4, 5, 6]) + @test transform(df, p; cols=[:b]) == DataFrame(:a => [1, 2, 3], :b => [64, 125, 216]) + + _df = deepcopy(df) + transform!(_df, p) + @test _df == expected + end + end diff --git a/test/runtests.jl b/test/runtests.jl index 55e9d46..f7989df 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,6 @@ +using AxisArrays +using AxisKeys +using DataFrames: DataFrame using Transform using Transform: _try_copy using Test From 9c8eda32cd520f6081743571539c881053da554b Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Thu, 28 Jan 2021 19:06:20 +0000 Subject: [PATCH 08/17] Rename package to Transforms --- .travis.yml | 4 ++-- Project.toml | 2 +- README.md | 8 +++---- docs/Manifest.toml | 2 +- docs/Project.toml | 2 +- docs/make.jl | 12 +++++----- docs/src/index.md | 6 ++--- src/{Transform.jl => Transforms.jl} | 4 ++-- src/power.jl | 4 ++-- src/transformers.jl | 34 ++++++++++++++--------------- test/power.jl | 2 +- test/runtests.jl | 6 ++--- 12 files changed, 43 insertions(+), 43 deletions(-) rename src/{Transform.jl => Transforms.jl} (71%) diff --git a/.travis.yml b/.travis.yml index 2e49e68..409b1ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ jobs: Pkg.develop(PackageSpec(path=pwd())) Pkg.instantiate() using Documenter: doctest - using Transform - doctest(Transform) + using Transforms + doctest(Transforms) include("docs/make.jl")' after_success: skip diff --git a/Project.toml b/Project.toml index 8595ab9..094fcd5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,4 +1,4 @@ -name = "Transform" +name = "Transforms" uuid = "8fd68953-04b8-4117-ac19-158bf6de9782" authors = ["Invenia Technical Computing Corporation"] version = "0.1.0" diff --git a/README.md b/README.md index 416dc32..203e419 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# Transform +# Transforms -[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://invenia.github.io/Transform.jl/stable) -[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://invenia.github.io/Transform.jl/dev) -[![Build Status](https://travis-ci.com/invenia/Transform.jl.svg?branch=master)](https://travis-ci.com/invenia/Transform.jl) +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://invenia.github.io/Transforms.jl/stable) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://invenia.github.io/Transforms.jl/dev) +[![Build Status](https://travis-ci.com/invenia/Transforms.jl.svg?branch=master)](https://travis-ci.com/invenia/Transforms.jl) [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle) [![ColPrac: Contributor's Guide on Collaborative Practices for Community Packages](https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet)](https://github.com/SciML/ColPrac) diff --git a/docs/Manifest.toml b/docs/Manifest.toml index cb44c18..4cfe025 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -91,7 +91,7 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -[[Transform]] +[[Transforms]] path = ".." uuid = "8fd68953-04b8-4117-ac19-158bf6de9782" version = "0.1.0" diff --git a/docs/Project.toml b/docs/Project.toml index 5759269..7dcc941 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,3 +1,3 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -Transform = "8fd68953-04b8-4117-ac19-158bf6de9782" +Transforms = "8fd68953-04b8-4117-ac19-158bf6de9782" diff --git a/docs/make.jl b/docs/make.jl index 899cd9d..3d812bf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,14 +1,14 @@ -using Transform +using Transforms using Documenter makedocs(; - modules=[Transform], + modules=[Transforms], authors="Invenia Technical Computing Corporation", - repo="https://github.com/invenia/Transform.jl/blob/{commit}{path}#L{line}", - sitename="Transform.jl", + repo="https://github.com/invenia/Transforms.jl/blob/{commit}{path}#L{line}", + sitename="Transforms.jl", format=Documenter.HTML(; prettyurls=get(ENV, "CI", "false") == "true", - canonical="https://invenia.github.io/Transform.jl", + canonical="https://invenia.github.io/Transforms.jl", assets=String[], ), pages=[ @@ -19,5 +19,5 @@ makedocs(; ) deploydocs(; - repo="github.com/invenia/Transform.jl", + repo="github.com/invenia/Transforms.jl", ) diff --git a/docs/src/index.md b/docs/src/index.md index 1805f0d..f3ed79b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,12 +1,12 @@ ```@meta -CurrentModule = Transform +CurrentModule = Transforms ``` -# Transform +# Transforms ```@index ``` ```@autodocs -Modules = [Transform] +Modules = [Transforms] ``` diff --git a/src/Transform.jl b/src/Transforms.jl similarity index 71% rename from src/Transform.jl rename to src/Transforms.jl index ae90c3a..e723320 100644 --- a/src/Transform.jl +++ b/src/Transforms.jl @@ -1,8 +1,8 @@ -module Transform +module Transforms using Tables -export Transformation, Power +export Transform, Power export transform, transform! include("utils.jl") diff --git a/src/power.jl b/src/power.jl index af58a21..8d8c41b 100644 --- a/src/power.jl +++ b/src/power.jl @@ -1,9 +1,9 @@ """ - Power(exponent) <: Transformation + Power(exponent) <: Transform Raise the data by the given `exponent`. """ -struct Power <: Transformation +struct Power <: Transform exponent::Real end diff --git a/src/transformers.jl b/src/transformers.jl index bf4619d..998c619 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -1,38 +1,38 @@ """ - Transformation + Transform -Abstract supertype for all transformations. +Abstract supertype for all Transforms. """ -abstract type Transformation end +abstract type Transform end # Make Transforms callable types -(t::Transformation)(x; kwargs...) = transform(x, t; kwargs...) +(t::Transform)(x; kwargs...) = transform(x, t; kwargs...) """ - transform!(data::T, transformation::Transformation; kwargs...) -> T + transform!(data::T, Transform::Transform; kwargs...) -> T -Apply the`transformation` mutating the input `data`. +Apply the`Transform` mutating the input `data`. Where possible, this should be extended for new data types `T`. """ function transform! end """ - transform(data::T, transformation::Transformation; kwargs...) -> T + transform(data::T, Transform::Transform; kwargs...) -> T Non-mutating version of [`transform!`](@ref), which it delegates to by default. -Does not need to be extended unless a mutating transformation is not possible. +Does not need to be extended unless a mutating Transform is not possible. """ function transform end """ - transform!(A::AbstractArray{T}, ::Transformation; dims=:, kwargs...) where T <: Real + transform!(A::AbstractArray{T}, ::Transform; dims=:, kwargs...) where T <: Real -Applies the transformation to each element of `A`. -Optionally specify the `dims` to apply the transformation along certain dimensions. +Applies the Transform to each element of `A`. +Optionally specify the `dims` to apply the Transform along certain dimensions. """ function transform!( - A::AbstractArray{T}, t::Transformation; dims=:, kwargs... + A::AbstractArray{T}, t::Transform; dims=:, kwargs... ) where T <: Real dims == Colon() && return _transform!(A, t; kwargs...) @@ -43,15 +43,15 @@ function transform!( return A end -transform(x, t::Transformation; kwargs...) = transform!(_try_copy(x), t; kwargs...) +transform(x, t::Transform; kwargs...) = transform!(_try_copy(x), t; kwargs...) """ - transform!(table::T, ::Transformation; cols=nothing)::T where T + transform!(table::T, ::Transform; cols=nothing)::T where T -Applies the transformation to each of the specified columns in the `table`. -If no `cols` are specified, then the transformation is applied to all columns. +Applies the Transform to each of the specified columns in the `table`. +If no `cols` are specified, then the Transform is applied to all columns. """ -function transform!(table::T, t::Transformation; cols=nothing)::T where T +function transform!(table::T, t::Transform; cols=nothing)::T where T # TODO: We could probably handle iterators of tables here Tables.istable(table) || throw(MethodError(transform!, (table, t))) diff --git a/test/power.jl b/test/power.jl index 6a2156e..77944df 100644 --- a/test/power.jl +++ b/test/power.jl @@ -1,7 +1,7 @@ @testset "power" begin p = Power(3) - @test p isa Transformation + @test p isa Transform # TODO: all of these should be part of some test utils @testset "Vector" begin diff --git a/test/runtests.jl b/test/runtests.jl index f7989df..896b32d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,10 +1,10 @@ using AxisArrays using AxisKeys using DataFrames: DataFrame -using Transform -using Transform: _try_copy +using Transforms +using Transforms: _try_copy using Test -@testset "Transform.jl" begin +@testset "Transforms.jl" begin include("power.jl") end From b91e73fe76453e314bc8ccf7d24ffbc41afb8a2e Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Fri, 29 Jan 2021 20:05:07 +0000 Subject: [PATCH 09/17] add space Co-authored-by: Ben Cottier --- src/transformers.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers.jl b/src/transformers.jl index 998c619..7e61232 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -12,7 +12,7 @@ abstract type Transform end """ transform!(data::T, Transform::Transform; kwargs...) -> T -Apply the`Transform` mutating the input `data`. +Apply the `Transform` mutating the input `data`. Where possible, this should be extended for new data types `T`. """ function transform! end From 27cc6fc58030bc4d48b174c27e274d80f366b949 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 12:51:28 +0000 Subject: [PATCH 10/17] Rename transform -> apply --- src/Transforms.jl | 1 - src/power.jl | 2 +- src/transformers.jl | 42 +++++++++++++++++++++--------------------- test/power.jl | 30 +++++++++++++++--------------- 4 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/Transforms.jl b/src/Transforms.jl index e723320..44ddc37 100644 --- a/src/Transforms.jl +++ b/src/Transforms.jl @@ -3,7 +3,6 @@ module Transforms using Tables export Transform, Power -export transform, transform! include("utils.jl") include("transformers.jl") diff --git a/src/power.jl b/src/power.jl index 8d8c41b..95010a5 100644 --- a/src/power.jl +++ b/src/power.jl @@ -7,7 +7,7 @@ struct Power <: Transform exponent::Real end -function _transform!(x::AbstractArray{T}, P::Power; kwargs...) where T <: Real +function _apply!(x::AbstractArray{T}, P::Power; kwargs...) where T <: Real x[:] = x .^ P.exponent return x end diff --git a/src/transformers.jl b/src/transformers.jl index 7e61232..bcd0c1c 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -7,53 +7,53 @@ Abstract supertype for all Transforms. abstract type Transform end # Make Transforms callable types -(t::Transform)(x; kwargs...) = transform(x, t; kwargs...) +(t::Transform)(x; kwargs...) = apply(x, t; kwargs...) """ - transform!(data::T, Transform::Transform; kwargs...) -> T + apply!(data::T, Transform::Transform; kwargs...) -> T -Apply the `Transform` mutating the input `data`. +Applies the [`Transform`](@ref) mutating the input `data`. Where possible, this should be extended for new data types `T`. """ -function transform! end +function apply! end """ - transform(data::T, Transform::Transform; kwargs...) -> T + apply(data::T, Transform::Transform; kwargs...) -> T -Non-mutating version of [`transform!`](@ref), which it delegates to by default. -Does not need to be extended unless a mutating Transform is not possible. +Non-mutating version of [`apply!`](@ref), which it delegates to by default. +Does not need to be extended unless a mutating [`Transform`](@ref) is not possible. """ -function transform end +function apply end """ - transform!(A::AbstractArray{T}, ::Transform; dims=:, kwargs...) where T <: Real + apply!(A::AbstractArray{T}, ::Transform; dims=:, kwargs...) where T <: Real -Applies the Transform to each element of `A`. -Optionally specify the `dims` to apply the Transform along certain dimensions. +Applies the [`Transform`](@ref) to each element of `A`. +Optionally specify the `dims` to apply the [`Transform`](@ref) along certain dimensions. """ -function transform!( +function apply!( A::AbstractArray{T}, t::Transform; dims=:, kwargs... ) where T <: Real - dims == Colon() && return _transform!(A, t; kwargs...) + dims == Colon() && return _apply!(A, t; kwargs...) for x in eachslice(A; dims=dims) - _transform!(x, t; kwargs...) + _apply!(x, t; kwargs...) end return A end -transform(x, t::Transform; kwargs...) = transform!(_try_copy(x), t; kwargs...) +apply(x, t::Transform; kwargs...) = apply!(_try_copy(x), t; kwargs...) """ - transform!(table::T, ::Transform; cols=nothing)::T where T + apply!(table::T, ::Transform; cols=nothing)::T where T -Applies the Transform to each of the specified columns in the `table`. -If no `cols` are specified, then the Transform is applied to all columns. +Applies the [`Transform`](@ref) to each of the specified columns in the `table`. +If no `cols` are specified, then the [`Transform`](@ref) is applied to all columns. """ -function transform!(table::T, t::Transform; cols=nothing)::T where T +function apply!(table::T, t::Transform; cols=nothing)::T where T # TODO: We could probably handle iterators of tables here - Tables.istable(table) || throw(MethodError(transform!, (table, t))) + Tables.istable(table) || throw(MethodError(apply!, (table, t))) # Extract a columns iterator that we should be able to use to mutate the data. # NOTE: Mutation is not guaranteed for all table types, but it avoid copying the data @@ -61,7 +61,7 @@ function transform!(table::T, t::Transform; cols=nothing)::T where T cnames = cols === nothing ? propertynames(columntable) : cols for cname in cnames - transform!(getproperty(columntable, cname), t) + apply!(getproperty(columntable, cname), t) end return table diff --git a/test/power.jl b/test/power.jl index 77944df..8f77ff4 100644 --- a/test/power.jl +++ b/test/power.jl @@ -8,11 +8,11 @@ x = [1, 2, 3, 4, 5] expected = [1, 8, 27, 64, 125] - @test transform(x, p) == expected + @test Transforms.apply(x, p) == expected @test p(x) == expected _x = copy(x) - transform!(_x, p) + Transforms.apply!(_x, p) @test _x == expected end @@ -21,11 +21,11 @@ expected = [1 8 27; 64 125 216] @testset "dims = $d" for d in (Colon(), 1, 2) - @test transform(M, p; dims=d) == expected + @test Transforms.apply(M, p; dims=d) == expected @test p(M; dims=d) == expected _M = copy(M) - transform!(_M, p; dims=d) + Transforms.apply!(_M, p; dims=d) @test _M == expected end end @@ -35,11 +35,11 @@ expected = (a = [1, 8, 27], b = [64, 125, 216]) @testset "all cols" begin - @test transform(nt, p) == expected + @test Transforms.apply(nt, p) == expected @test p(nt) == expected _nt = deepcopy(nt) - transform!(_nt, p) + Transforms.apply!(_nt, p) @test _nt == expected end @@ -47,11 +47,11 @@ nt_mutated = NamedTuple{(Symbol("$c"), )}((expected[c], )) nt_expected = merge(nt, nt_mutated) - @test transform(nt, p; cols=[c]) == nt_expected + @test Transforms.apply(nt, p; cols=[c]) == nt_expected @test p(nt; cols=[c]) == nt_expected _nt = deepcopy(nt) - transform!(_nt, p; cols=[c]) + Transforms.apply!(_nt, p; cols=[c]) @test _nt == nt_expected end end @@ -61,7 +61,7 @@ expected = AxisArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) @testset "dims = $d" for d in (Colon(), 1, 2) - @test transform(A, p; dims=d) == expected + @test Transforms.apply(A, p; dims=d) == expected end end @@ -71,11 +71,11 @@ expected = AxisArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) @testset "dims = $d" for d in (Colon(), :foo, :bar) - @test transform(A, p; dims=d) == expected + @test Transforms.apply(A, p; dims=d) == expected end _A = copy(A) - transform!(_A, p) + Transforms.apply!(_A, p) @test _A == expected end @@ -83,12 +83,12 @@ df = DataFrame(:a => [1, 2, 3], :b => [4, 5, 6]) expected = DataFrame(:a => [1, 8, 27], :b => [64, 125, 216]) - @test transform(df, p) == expected - @test transform(df, p; cols=[:a]) == DataFrame(:a => [1, 8, 27], :b => [4, 5, 6]) - @test transform(df, p; cols=[:b]) == DataFrame(:a => [1, 2, 3], :b => [64, 125, 216]) + @test Transforms.apply(df, p) == expected + @test Transforms.apply(df, p; cols=[:a]) == DataFrame(:a => [1, 8, 27], :b => [4, 5, 6]) + @test Transforms.apply(df, p; cols=[:b]) == DataFrame(:a => [1, 2, 3], :b => [64, 125, 216]) _df = deepcopy(df) - transform!(_df, p) + Transforms.apply!(_df, p) @test _df == expected end From 5226f179000fe5d78d05798f728fc6ddc7d59420 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 12:57:03 +0000 Subject: [PATCH 11/17] Qualify Transforms.apply docstrings --- src/transformers.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transformers.jl b/src/transformers.jl index bcd0c1c..4dc3db6 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -10,7 +10,7 @@ abstract type Transform end (t::Transform)(x; kwargs...) = apply(x, t; kwargs...) """ - apply!(data::T, Transform::Transform; kwargs...) -> T + Transforms.apply!(data::T, Transform::Transform; kwargs...) -> T Applies the [`Transform`](@ref) mutating the input `data`. Where possible, this should be extended for new data types `T`. @@ -18,7 +18,7 @@ Where possible, this should be extended for new data types `T`. function apply! end """ - apply(data::T, Transform::Transform; kwargs...) -> T + Transforms.apply(data::T, Transform::Transform; kwargs...) -> T Non-mutating version of [`apply!`](@ref), which it delegates to by default. Does not need to be extended unless a mutating [`Transform`](@ref) is not possible. @@ -46,7 +46,7 @@ end apply(x, t::Transform; kwargs...) = apply!(_try_copy(x), t; kwargs...) """ - apply!(table::T, ::Transform; cols=nothing)::T where T + Transforms.apply!(table::T, ::Transform; cols=nothing)::T where T Applies the [`Transform`](@ref) to each of the specified columns in the `table`. If no `cols` are specified, then the [`Transform`](@ref) is applied to all columns. From 0a5519e01116e3bda0db0c2ad04027ab16206601 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 13:17:23 +0000 Subject: [PATCH 12/17] Define transform --- src/Transforms.jl | 1 + src/transformers.jl | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Transforms.jl b/src/Transforms.jl index 44ddc37..e723320 100644 --- a/src/Transforms.jl +++ b/src/Transforms.jl @@ -3,6 +3,7 @@ module Transforms using Tables export Transform, Power +export transform, transform! include("utils.jl") include("transformers.jl") diff --git a/src/transformers.jl b/src/transformers.jl index 4dc3db6..788bd37 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -9,6 +9,24 @@ abstract type Transform end # Make Transforms callable types (t::Transform)(x; kwargs...) = apply(x, t; kwargs...) + +""" + transform!(::T, data) + +Defines the feature engineering pipeline for some type `T`, which comprises a collection of +[`Transform`](@ref)s to be peformed on the `data`. + +`transform!` should be overloaded for custom types `T` that require feature engineering. +""" +function transform! end + +""" + transform(::T, data) + +Non-mutating version of [`transform!`](@ref). +""" +function transform end + """ Transforms.apply!(data::T, Transform::Transform; kwargs...) -> T From 409b5dc455dac49818ba886bfaaa429bab896809 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 17:45:20 +0000 Subject: [PATCH 13/17] fix typos --- src/transformers.jl | 4 ++-- test/power.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transformers.jl b/src/transformers.jl index 788bd37..238b8ef 100644 --- a/src/transformers.jl +++ b/src/transformers.jl @@ -28,7 +28,7 @@ Non-mutating version of [`transform!`](@ref). function transform end """ - Transforms.apply!(data::T, Transform::Transform; kwargs...) -> T + Transforms.apply!(data::T, ::Transform; kwargs...) -> T Applies the [`Transform`](@ref) mutating the input `data`. Where possible, this should be extended for new data types `T`. @@ -36,7 +36,7 @@ Where possible, this should be extended for new data types `T`. function apply! end """ - Transforms.apply(data::T, Transform::Transform; kwargs...) -> T + Transforms.apply(data::T, ::Transform; kwargs...) -> T Non-mutating version of [`apply!`](@ref), which it delegates to by default. Does not need to be extended unless a mutating [`Transform`](@ref) is not possible. diff --git a/test/power.jl b/test/power.jl index 8f77ff4..eb672f2 100644 --- a/test/power.jl +++ b/test/power.jl @@ -68,7 +68,7 @@ @testset "AxisKey" begin A = KeyedArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]) - expected = AxisArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) + expected = KeyedArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) @testset "dims = $d" for d in (Colon(), :foo, :bar) @test Transforms.apply(A, p; dims=d) == expected From a8adc6bd5fb0c2bec30b18219b3df35210422ef4 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 17:54:14 +0000 Subject: [PATCH 14/17] check types in test --- test/power.jl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/test/power.jl b/test/power.jl index eb672f2..a1ccb38 100644 --- a/test/power.jl +++ b/test/power.jl @@ -35,7 +35,9 @@ expected = (a = [1, 8, 27], b = [64, 125, 216]) @testset "all cols" begin - @test Transforms.apply(nt, p) == expected + transformed = Transforms.apply(nt, p) + @test transformed isa NamedTuple{(:a, :b)} + @test transformed == expected @test p(nt) == expected _nt = deepcopy(nt) @@ -61,7 +63,9 @@ expected = AxisArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) @testset "dims = $d" for d in (Colon(), 1, 2) - @test Transforms.apply(A, p; dims=d) == expected + transformed = Transforms.apply(A, p; dims=d) + @test transformed isa AxisArray + @test transformed == expected end end @@ -71,7 +75,9 @@ expected = KeyedArray([1 8 27; 64 125 216], foo=["a", "b"], bar=["x", "y", "z"]) @testset "dims = $d" for d in (Colon(), :foo, :bar) - @test Transforms.apply(A, p; dims=d) == expected + transformed = Transforms.apply(A, p; dims=d) + @test transformed isa KeyedArray + @test transformed == expected end _A = copy(A) @@ -83,7 +89,10 @@ df = DataFrame(:a => [1, 2, 3], :b => [4, 5, 6]) expected = DataFrame(:a => [1, 8, 27], :b => [64, 125, 216]) - @test Transforms.apply(df, p) == expected + transformed = Transforms.apply(df, p) + @test transformed isa DataFrame + @test transformed == expected + @test Transforms.apply(df, p; cols=[:a]) == DataFrame(:a => [1, 8, 27], :b => [4, 5, 6]) @test Transforms.apply(df, p; cols=[:b]) == DataFrame(:a => [1, 2, 3], :b => [64, 125, 216]) From 1057b7dcd0c352d8e7b5c836b08bc8405c7cb4d5 Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 18:32:43 +0000 Subject: [PATCH 15/17] Run CI through GitHub Actions --- .github/workflows/CI.yml | 94 ++++++++++++++++++++++++++++++ .github/workflows/CompatHelper.yml | 2 +- .github/workflows/JuliaNightly.yml | 29 +++++++++ .travis.yml | 34 ----------- 4 files changed, 124 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/CI.yml create mode 100644 .github/workflows/JuliaNightly.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..bab7837 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,94 @@ +name: CI +# Run on master, tags, or any pull request +on: + schedule: + - cron: '0 2 * * *' # Daily at 2 AM UTC (8 PM CST) + push: + branches: [master] + tags: ["*"] + pull_request: +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - "1.0" # LTS + - "1" # Latest Release + os: + - ubuntu-latest + - macOS-latest + - windows-latest + arch: + - x64 + - x86 + exclude: + # Test 32-bit only on Linux + - os: macOS-latest + arch: x86 + - os: windows-latest + arch: x86 + include: + # Add a 1.5 job because that's what Invenia actually uses + - os: ubuntu-latest + version: 1.5 + arch: x64 + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: actions/cache@v2 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-${{ matrix.arch }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-${{ matrix.arch }}-test-${{ env.cache-name }}- + ${{ runner.os }}-${{ matrix.arch }}-test- + ${{ runner.os }}-${{ matrix.arch }}- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v1 + with: + file: lcov.info + + slack: + name: Notify Slack Failure + needs: test + runs-on: ubuntu-latest + if: always() && github.event_name == 'schedule' + steps: + - uses: technote-space/workflow-conclusion-action@v2 + - uses: voxmedia/github-action-slack-notify-build@v1 + if: env.WORKFLOW_CONCLUSION == 'failure' + with: + channel: nightly-rse + status: FAILED + color: danger + env: + SLACK_BOT_TOKEN: ${{ secrets.RSE_SLACK_BOT_TOKEN }} + + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: '1' + - run: | + julia --project=docs -e ' + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + include("docs/make.jl")' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index cba9134..6c96707 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -1,7 +1,7 @@ name: CompatHelper on: schedule: - - cron: 0 0 * * * + - cron: '0 0 * * *' # Everyday at midnight workflow_dispatch: jobs: CompatHelper: diff --git a/.github/workflows/JuliaNightly.yml b/.github/workflows/JuliaNightly.yml new file mode 100644 index 0000000..351eec9 --- /dev/null +++ b/.github/workflows/JuliaNightly.yml @@ -0,0 +1,29 @@ +name: JuliaNightly +# Nightly Scheduled Julia Nightly Run +on: + schedule: + - cron: '0 2 * * *' # Daily at 2 AM UTC (8 PM CST) +jobs: + test: + name: Julia Nightly - Ubuntu - x64 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: nightly + arch: x64 + - uses: actions/cache@v2 + env: + cache-name: julia-nightly-cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ env.cache-name }}- + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v1 + with: + file: lcov.info diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 409b1ae..0000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Documentation: http://docs.travis-ci.com/user/languages/julia -language: julia -notifications: - email: false -julia: - - 1 - - 1.0 - - nightly -os: - - linux - - osx - - windows -arch: - - x64 -cache: - directories: - - ~/.julia/artifacts -jobs: - fast_finish: true - allow_failures: - - julia: nightly - include: - - stage: Documentation - julia: 1 - script: | - julia --project=docs -e ' - using Pkg - Pkg.develop(PackageSpec(path=pwd())) - Pkg.instantiate() - using Documenter: doctest - using Transforms - doctest(Transforms) - include("docs/make.jl")' - after_success: skip From e7ba6389badbd462a624039fc4a1de46c4f13c4d Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Mon, 1 Feb 2021 19:16:29 +0000 Subject: [PATCH 16/17] Remove testing on 1.0 Although this is the current LTS we expect to make a lot of use of eachslice in the package which was only introduced in 1.1. Furthermore, the upcoming 1.6 release will be the new LTS. --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index bab7837..caa8dc8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: version: - - "1.0" # LTS + - "1.5" # Invenia Prod version - "1" # Latest Release os: - ubuntu-latest From b477f14683b21942ec87ba4735f3aa0301d9ce1a Mon Sep 17 00:00:00 2001 From: Glenn Moynihan Date: Tue, 2 Feb 2021 11:44:09 +0000 Subject: [PATCH 17/17] Restrict to Julia >=1.5 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 094fcd5..f9478c9 100644 --- a/Project.toml +++ b/Project.toml @@ -11,7 +11,7 @@ AxisArrays = "0.4" AxisKeys = "0.1" DataFrames = "0.22" Tables = "1.3" -julia = "1" +julia = "1.5" [extras] AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9"