You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DataFrames.jl的transform!实现独热编码遇参数错误的解决咨询

在DataFrames.jl中使用transform!实现独热编码的问题

我尝试用DataFrames.jl的transform!函数实现简单独热编码,但未成功。使用的DataFrame如下:

using DataFrames

df = DataFrame(
  color = ["red", "green", "blue"],
  x = [1, 2, 3]
)
# 3×2 DataFrame
#  Row │ color   x
#      │ String  Int64
# ─────┼───────────────
#    1 │ red         1
#    2 │ green       2
#    3 │ blue        3

我定义了一个返回编码矩阵的函数:

function OneHotEncod(vec::Vector{String})
  reduce(hcat, [vec .== i for i=vec])
end

运行以下代码时触发错误:

transform!(df, Cols(:color) => x -> OneHotEncod(x), renamecols=false)
# ERROR: ArgumentError: Table returned, but a single output column was expected

我理解错误原因,但想知道是否有办法在transform!中使用返回多向量(如矩阵)的函数?

附录:

OneHotEncod(df.color)
# 3×3 BitMatrix:
#  1  0  0
#  0  1  0
#  0  0  1

解决方案

方法1:用AsTable将矩阵转为表格输出

transform!默认期望函数返回单个列的内容,当返回矩阵时,它会将矩阵识别为表格(每一列对应一个表格列)。此时可以用AsTable明确告知要将矩阵的每一列作为新列添加到DataFrame中:

transform!(df, Cols(:color) => x -> OneHotEncod(x) |> AsTable, renamecols=false)

执行后会新增3列,默认列名为x1、x2、x3。如果需要自定义列名,可让函数返回带列名的NamedTuple:

transform!(df, :color => x -> NamedTuple(Symbol.(x) .=> eachcol(OneHotEncod(x))) => AsTable)

这样新增的列会直接用red、green、blue作为列名,更直观。

方法2:调整函数返回列迭代器

修改OneHotEncod函数,让它返回矩阵的列迭代器(eachcol(matrix)),然后在transform!中指定新列名:

function OneHotEncod(vec::Vector{String})
  mat = reduce(hcat, [vec .== i for i=vec])
  eachcol(mat)
end

# 指定新列名并执行transform!
transform!(df, :color => OneHotEncod => [:red, :green, :blue])

方法3:使用成熟的独热编码工具包

实际开发中更推荐用专门的工具包处理独热编码,避免手动实现的潜在问题:

基于OneHotArrays.jl:

using OneHotArrays

transform!(df, :color => x -> onehotbatch(x, unique(x)) |> eachcol => [:red, :green, :blue])

基于CategoricalArrays.jl:

using CategoricalArrays

# 先将color列转为分类类型
df.color = categorical(df.color)
# 生成哑变量列
transform!(df, :color => x -> dummycols(x)[1] => AsTable)

内容的提问来源于stack exchange,提问作者Shayan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:10:32