您将如何按列将函数应用于 julia 数据框中的某些/所有列?我试图解决的用例是简单的类型解析和处理。例如,我想将此示例数据帧的列从字符串解析为整数
df = DataFrame(a = ["1","2", "3"], b = ["4","5","6"])
# something like this works but destroys the structure of the dataframe
[parse.(Int64, col) for col in eachcol(df)]
Run Code Online (Sandbox Code Playgroud)
将来,我希望能够拥有一个包含许多不同类型列的数据框,并且只修改此数据框的选择。但是,我仍然坚持将函数应用于所有列的简单情况。
目前尚不清楚您想要达到的目标。根据您的评论,我假设您想将数据框作为源并获得数据框作为结果。如果是这种情况,这里是选项。
基本的一种是使用mapcols(创建一个新的数据框)或mapcols!(就地操作)。以下是mapcols您查询的示例:
julia> mapcols(col -> parse.(Int, col), df)
3×2 DataFrame
? Row ? a ? b ?
? ? Int64 ? Int64 ?
???????????????????????
? 1 ? 1 ? 4 ?
? 2 ? 2 ? 5 ?
? 3 ? 3 ? 6 ?
Run Code Online (Sandbox Code Playgroud)
一组更通用的函数是transform(创建一个新的数据框)和 `transform! (就地操作)。他们将新列添加到您的数据框中:
julia> transform(df, :a => ByRow(x -> parse(Int, x)) => :a)
3×2 DataFrame
? Row ? a ? b ?
? ? Int64 ? String ?
????????????????????????
? 1 ? 1 ? 4 ?
? 2 ? 2 ? 5 ?
? 3 ? 3 ? 6 ?
julia> transform(df, [:a, :b] .=> ByRow(x -> parse(Int, x)) .=> [:a, :b])
3×2 DataFrame
? Row ? a ? b ?
? ? Int64 ? Int64 ?
???????????????????????
? 1 ? 1 ? 4 ?
? 2 ? 2 ? 5 ?
? 3 ? 3 ? 6 ?
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅 DataFrames.jl 的文档(因为它们很长 - 该函数有很多选项,但您可以从这里和这里开始)。
这里有几点需要注意:
transform比mapcols指定输出列的名称更通用(如果省略输出列名称,它将通过合并源列名称和函数名称自动生成)transform到列的子集,但是请注意,为了将相同的转换应用于多个列,我们使用了带.=>符号的广播。(请注意,有select和select!功能几乎相同,但默认情况下不保留旧数据框的列)
最后,在实践中,写这样的东西也是完全可以的:
julia> foreach(n -> df[!, n] = parse.(Int, df[!, n]), names(df))
julia> df
3×2 DataFrame
? Row ? a ? b ?
? ? Int64 ? Int64 ?
???????????????????????
? 1 ? 1 ? 4 ?
? 2 ? 2 ? 5 ?
? 3 ? 3 ? 6 ?
Run Code Online (Sandbox Code Playgroud)
(如您所见,这会就地修改您的数据框)