Julia DataFrames - 如何进行单热编码?
Julia DataFrames - How to do one-hot encoding?
我正在使用 Julia 的 DataFrames.jl 包。在其中,我有一个数据框,其中包含一个包含字符串列表的列(例如 ["Type A", "Type B", "Type D"])。然后如何执行单热编码?我无法在 DataFrames.jl 包中找到预建函数。
这是我想做的事的一个例子:
Original Dataframe
col1 | col2 |
102 |[a] |
103 |[a,b] |
102 |[c,b] |
After One-hot encoding
col1 | a | b | c |
102 | 1 | 0 | 0 |
103 | 1 | 1 | 0 |
102 | 0 | 1 | 1 |
DataFrames.jl 中确实没有 one-hot 编码函数 - 我认为这是明智的,因为这是一个特殊的机器学习转换,应该存在于 ML 包中而不是一个基本的 DataFrames 包。
我认为你有两个选择:
使用可以为您完成此操作的 ML 包,例如MLJ.jl. In MLJ, the OneHotEncoder
is a model that transforms any table with Finite
features in it into a one-hot encoded version of itself, see the docs here
使用一个回归包,它使用 StatsModels @formula
API 自动为分类变量生成虚拟列 - 如果你用例如拟合回归GLM.jl
并且您的公式是 @formula(y ~ x)
其中 x
是一个分类变量,模型矩阵将通过对比编码 x
自动构建,即除一个之外的所有列都具有二进制虚拟列x
的水平
对于第二个选项,理想情况下您希望数据是分类的(尽管字符串也可以),为此 DataFrames.jl 包含 categorical!
函数。
编辑 2021 年 11 月 17 日:此后在 Julia Discourse 上有一个明确的主题,其中包含关于执行 one-hot 编码的广泛建议列表:https://discourse.julialang.org/t/all-the-ways-to-do-one-hot-encoding/
从那里分享我最喜欢的:
julia> x = [1, 2, 1, 3, 2];
julia> unique(x) .== permutedims(x)
3×5 BitMatrix:
1 0 1 0 0
0 1 0 0 1
0 0 0 1 0
使用我们提供的基本功能很容易做到:
julia> df = DataFrame(x=rand([1:3;missing], 20))
20×1 DataFrame
│ Row │ x │
│ │ Int64? │
├─────┼─────────┤
│ 1 │ 1 │
│ 2 │ 2 │
│ 3 │ missing │
│ 4 │ 1 │
│ 5 │ 3 │
│ 6 │ missing │
│ 7 │ 3 │
│ 8 │ 3 │
│ 9 │ 3 │
│ 10 │ 3 │
│ 11 │ missing │
│ 12 │ 1 │
│ 13 │ 3 │
│ 14 │ 3 │
│ 15 │ 3 │
│ 16 │ 1 │
│ 17 │ missing │
│ 18 │ 1 │
│ 19 │ 1 │
│ 20 │ missing │
julia> ux = unique(df.x); transform(df, @. :x => ByRow(isequal(ux)) .=> Symbol(:x_, ux))
20×5 DataFrame
│ Row │ x │ x_1 │ x_2 │ x_missing │ x_3 │
│ │ Int64? │ Bool │ Bool │ Bool │ Bool │
├─────┼─────────┼──────┼──────┼───────────┼──────┤
│ 1 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 2 │ 2 │ 0 │ 1 │ 0 │ 0 │
│ 3 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 4 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 5 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 6 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 7 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 8 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 9 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 10 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 11 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 12 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 13 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 14 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 15 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 16 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 17 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 18 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 19 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 20 │ missing │ 0 │ 0 │ 1 │ 0 │
编辑:
另一个例子:
julia> df = DataFrame(col1=102:104, col2=[["a"], ["a","b"], ["c","b"]])
3×2 DataFrame
│ Row │ col1 │ col2 │
│ │ Int64 │ Array… │
├─────┼───────┼────────────┤
│ 1 │ 102 │ ["a"] │
│ 2 │ 103 │ ["a", "b"] │
│ 3 │ 104 │ ["c", "b"] │
julia> ux = unique(reduce(vcat, df.col2))
3-element Array{String,1}:
"a"
"b"
"c"
julia> transform(df, :col2 .=> [ByRow(v -> x in v) for x in ux] .=> Symbol.(:col2_, ux))
3×5 DataFrame
│ Row │ col1 │ col2 │ col2_a │ col2_b │ col2_c │
│ │ Int64 │ Array… │ Bool │ Bool │ Bool │
├─────┼───────┼────────────┼────────┼────────┼────────┤
│ 1 │ 102 │ ["a"] │ 1 │ 0 │ 0 │
│ 2 │ 103 │ ["a", "b"] │ 1 │ 1 │ 0 │
│ 3 │ 104 │ ["c", "b"] │ 0 │ 1 │ 1 │
我已经包含了一个基于@Bogumil 代码的热门函数
https://github.com/xiaodaigh/DataConvenience.jl#one-hot-encoding
随心所欲
onehot(df, :col2)
完整的 MWE
a = DataFrame(
player1 = ["a", "b", "c"],
player2 = ["d", "c", "a"]
)
# does not modify a
onehot(a, :player1)
# modfies a
onehot!(a, :player1)
我正在使用 Julia 的 DataFrames.jl 包。在其中,我有一个数据框,其中包含一个包含字符串列表的列(例如 ["Type A", "Type B", "Type D"])。然后如何执行单热编码?我无法在 DataFrames.jl 包中找到预建函数。
这是我想做的事的一个例子:
Original Dataframe
col1 | col2 |
102 |[a] |
103 |[a,b] |
102 |[c,b] |
After One-hot encoding
col1 | a | b | c |
102 | 1 | 0 | 0 |
103 | 1 | 1 | 0 |
102 | 0 | 1 | 1 |
DataFrames.jl 中确实没有 one-hot 编码函数 - 我认为这是明智的,因为这是一个特殊的机器学习转换,应该存在于 ML 包中而不是一个基本的 DataFrames 包。
我认为你有两个选择:
使用可以为您完成此操作的 ML 包,例如MLJ.jl. In MLJ, the
OneHotEncoder
is a model that transforms any table withFinite
features in it into a one-hot encoded version of itself, see the docs here使用一个回归包,它使用 StatsModels
的水平@formula
API 自动为分类变量生成虚拟列 - 如果你用例如拟合回归GLM.jl
并且您的公式是@formula(y ~ x)
其中x
是一个分类变量,模型矩阵将通过对比编码x
自动构建,即除一个之外的所有列都具有二进制虚拟列x
对于第二个选项,理想情况下您希望数据是分类的(尽管字符串也可以),为此 DataFrames.jl 包含 categorical!
函数。
编辑 2021 年 11 月 17 日:此后在 Julia Discourse 上有一个明确的主题,其中包含关于执行 one-hot 编码的广泛建议列表:https://discourse.julialang.org/t/all-the-ways-to-do-one-hot-encoding/
从那里分享我最喜欢的:
julia> x = [1, 2, 1, 3, 2];
julia> unique(x) .== permutedims(x)
3×5 BitMatrix:
1 0 1 0 0
0 1 0 0 1
0 0 0 1 0
使用我们提供的基本功能很容易做到:
julia> df = DataFrame(x=rand([1:3;missing], 20))
20×1 DataFrame
│ Row │ x │
│ │ Int64? │
├─────┼─────────┤
│ 1 │ 1 │
│ 2 │ 2 │
│ 3 │ missing │
│ 4 │ 1 │
│ 5 │ 3 │
│ 6 │ missing │
│ 7 │ 3 │
│ 8 │ 3 │
│ 9 │ 3 │
│ 10 │ 3 │
│ 11 │ missing │
│ 12 │ 1 │
│ 13 │ 3 │
│ 14 │ 3 │
│ 15 │ 3 │
│ 16 │ 1 │
│ 17 │ missing │
│ 18 │ 1 │
│ 19 │ 1 │
│ 20 │ missing │
julia> ux = unique(df.x); transform(df, @. :x => ByRow(isequal(ux)) .=> Symbol(:x_, ux))
20×5 DataFrame
│ Row │ x │ x_1 │ x_2 │ x_missing │ x_3 │
│ │ Int64? │ Bool │ Bool │ Bool │ Bool │
├─────┼─────────┼──────┼──────┼───────────┼──────┤
│ 1 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 2 │ 2 │ 0 │ 1 │ 0 │ 0 │
│ 3 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 4 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 5 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 6 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 7 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 8 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 9 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 10 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 11 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 12 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 13 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 14 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 15 │ 3 │ 0 │ 0 │ 0 │ 1 │
│ 16 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 17 │ missing │ 0 │ 0 │ 1 │ 0 │
│ 18 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 19 │ 1 │ 1 │ 0 │ 0 │ 0 │
│ 20 │ missing │ 0 │ 0 │ 1 │ 0 │
编辑:
另一个例子:
julia> df = DataFrame(col1=102:104, col2=[["a"], ["a","b"], ["c","b"]])
3×2 DataFrame
│ Row │ col1 │ col2 │
│ │ Int64 │ Array… │
├─────┼───────┼────────────┤
│ 1 │ 102 │ ["a"] │
│ 2 │ 103 │ ["a", "b"] │
│ 3 │ 104 │ ["c", "b"] │
julia> ux = unique(reduce(vcat, df.col2))
3-element Array{String,1}:
"a"
"b"
"c"
julia> transform(df, :col2 .=> [ByRow(v -> x in v) for x in ux] .=> Symbol.(:col2_, ux))
3×5 DataFrame
│ Row │ col1 │ col2 │ col2_a │ col2_b │ col2_c │
│ │ Int64 │ Array… │ Bool │ Bool │ Bool │
├─────┼───────┼────────────┼────────┼────────┼────────┤
│ 1 │ 102 │ ["a"] │ 1 │ 0 │ 0 │
│ 2 │ 103 │ ["a", "b"] │ 1 │ 1 │ 0 │
│ 3 │ 104 │ ["c", "b"] │ 0 │ 1 │ 1 │
我已经包含了一个基于@Bogumil 代码的热门函数
https://github.com/xiaodaigh/DataConvenience.jl#one-hot-encoding
随心所欲
onehot(df, :col2)
完整的 MWE
a = DataFrame(
player1 = ["a", "b", "c"],
player2 = ["d", "c", "a"]
)
# does not modify a
onehot(a, :player1)
# modfies a
onehot!(a, :player1)