有没有办法一次减去多个数据框列?

gre*_*ner 2 julia

我对 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)

但这会产生错误。那么如何修改这种方法以成功减去多列数据帧行呢?

非常感谢!

Bog*_*ski 5

不幸的是,这项特殊任务有点棘手,因为我们试图保持与 Julia Base 的一致性。

以下是方法:

选项1

使用迭代:

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)

选项 2

使用数据帧广播:

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)

选项 3

这是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)