我对 Julia 很陌生,所以如果这是一个超级基本的问题,我深表歉意。从 R 开始,我习惯于一次对数据帧的多列进行基本操作。我尝试通过以下方式在 Julia 中执行此操作:
我有两个数据帧,我们称它们为 data_1 和 data_2:
using DataFrames
data_1 = DataFrame(rand(4,6))
data_2 = DataFrame(zeros(4,6))
Run Code Online (Sandbox Code Playgroud)
现在我想填充 data_2 作为某些行与 data_1 的差异,例如:
data_2[1,:] = data_1[1,:] - data_1[2,:]
Run Code Online (Sandbox Code Playgroud)
但这会产生错误。那么如何修改这种方法以成功减去多列数据帧行呢?
非常感谢!
不幸的是,这项特殊任务有点棘手,因为我们试图保持与 Julia Base 的一致性。
以下是方法:
使用迭代:
julia> data_1 = DataFrame(reshape(1:24, 4, 6))
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Int64 ? Int64 ? Int64 ? Int64 ? Int64 ? Int64 ?
???????????????????????????????????????????????????????
? 1 ? 1 ? 5 ? 9 ? 13 ? 17 ? 21 ?
? 2 ? 2 ? 6 ? 10 ? 14 ? 18 ? 22 ?
? 3 ? 3 ? 7 ? 11 ? 15 ? 19 ? 23 ?
? 4 ? 4 ? 8 ? 12 ? 16 ? 20 ? 24 ?
julia> data_2 = DataFrame(zeros(4,6))
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 2 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 3 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 4 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
julia> foreach(i -> data_2[1,i] = data_1[1, i] - data_1[2, i], axes(data_1, 2))
julia> data_2
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ?
? 2 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 3 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 4 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
Run Code Online (Sandbox Code Playgroud)
使用数据帧广播:
julia> data_1 = DataFrame(reshape(1:24, 4, 6))
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Int64 ? Int64 ? Int64 ? Int64 ? Int64 ? Int64 ?
???????????????????????????????????????????????????????
? 1 ? 1 ? 5 ? 9 ? 13 ? 17 ? 21 ?
? 2 ? 2 ? 6 ? 10 ? 14 ? 18 ? 22 ?
? 3 ? 3 ? 7 ? 11 ? 15 ? 19 ? 23 ?
? 4 ? 4 ? 8 ? 12 ? 16 ? 20 ? 24 ?
julia> data_2
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ?
? 2 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 3 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 4 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
julia> data_2[1:1,:] .= data_1[1:1,:] .- data_1[2:2,:]
1×6 SubDataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ?
julia> data_2
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ?
? 2 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 3 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 4 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
Run Code Online (Sandbox Code Playgroud)
如您所见,诀窍是使用广播(the .)和切片(1:1等)而不是单个索引。
单一索引的问题是DataFrameRow现在不支持广播:
julia> data_2[1,:] .= data_1[1,:] .- data_1[2,:]
ERROR: ArgumentError: broadcasting over `DataFrameRow`s is reserved
Run Code Online (Sandbox Code Playgroud)
因为尚未决定广播将如何用于NamedTupleBase 中的对象,正如您在此处看到的:
julia> (a=1,b=2) .- (a=1,b=2)
ERROR: ArgumentError: broadcasting over dictionaries and `NamedTuple`s is reserved
Run Code Online (Sandbox Code Playgroud)
(一旦 Base 支持广播,NamedTuples我们就会将此支持添加到DataFrameRows)
这是DataFrameRow对象无广播问题的解决方法:
julia> data_1 = DataFrame(reshape(1:24, 4, 6))
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Int64 ? Int64 ? Int64 ? Int64 ? Int64 ? Int64 ?
???????????????????????????????????????????????????????
? 1 ? 1 ? 5 ? 9 ? 13 ? 17 ? 21 ?
? 2 ? 2 ? 6 ? 10 ? 14 ? 18 ? 22 ?
? 3 ? 3 ? 7 ? 11 ? 15 ? 19 ? 23 ?
? 4 ? 4 ? 8 ? 12 ? 16 ? 20 ? 24 ?
julia> data_2 = DataFrame(zeros(4,6))
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 2 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 3 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 4 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
julia> data_2[1,:] = Vector(data_1[1,:]) - Vector(data_1[2,:])
DataFrameRow
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ?
julia> data_2
4×6 DataFrame
? Row ? x1 ? x2 ? x3 ? x4 ? x5 ? x6 ?
? ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ? Float64 ?
???????????????????????????????????????????????????????????????????
? 1 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ? -1.0 ?
? 2 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 3 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
? 4 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ? 0.0 ?
Run Code Online (Sandbox Code Playgroud)
如您所见,诀窍是将 RHS 转换为Vector支持-.
最后(作为在某些情况下可能有用的附加参考),您可以编写Vector(data_1[1,:]) - Vector(data_1[2,:])更短的代码:
julia> -(Vector.((data_1[1,:],data_1[2,:]))...)
6-element Array{Int64,1}:
-1
-1
-1
-1
-1
-1
Run Code Online (Sandbox Code Playgroud)