我在 Julia 中有以下数据框。
using DataFrames
data = DataFrame(Value = [23, 56, 10, 48, 51], Type = ["A", "B", "A", "B", "B"])
5×2 DataFrame
? Row ? Value ? Type ?
? ? Int64 ? String ?
????????????????????????
? 1 ? 23 ? A ?
? 2 ? 56 ? B ?
? 3 ? 10 ? A ?
? 4 ? 48 ? B ?
? 5 ? 51 ? B ?
Run Code Online (Sandbox Code Playgroud)
如何根据列Type获得列Value的平均值?
如果您想要性能,请考虑以下选项
julia> using DataFrames
julia> using Statistics
julia> using BenchmarkTools
julia> data = DataFrame(Value = rand(1:10, 10^6),
Type = categorical(rand(["A", "B"], 10^6)));
Run Code Online (Sandbox Code Playgroud)
请注意,我将:Type
列生成为分类列,因为稍后聚合会快得多。
首先是上面答案的时间:
julia> @benchmark by($data, [:Type], df -> mean(df[:, :Value]))
BenchmarkTools.Trial:
memory estimate: 30.53 MiB
allocs estimate: 212
--------------
minimum time: 12.173 ms (0.00% GC)
median time: 13.305 ms (3.63% GC)
mean time: 14.229 ms (4.30% GC)
maximum time: 20.491 ms (2.98% GC)
--------------
samples: 352
evals/sample: 1
Run Code Online (Sandbox Code Playgroud)
这是我更改df[:, :Value]
为df.Value
. 不同之处在于df.Value
不会不必要地复制数据。您可以看到,您已经节省了 10% 以上的运行时间:
julia> @benchmark by($data, :Type, df -> mean(df.Value))
BenchmarkTools.Trial:
memory estimate: 22.90 MiB
allocs estimate: 203
--------------
minimum time: 10.926 ms (0.00% GC)
median time: 13.151 ms (1.92% GC)
mean time: 13.093 ms (3.53% GC)
maximum time: 16.933 ms (3.25% GC)
--------------
samples: 382
evals/sample: 1
Run Code Online (Sandbox Code Playgroud)
这是一种有效的编写方法。此语句意味着我们将列传递给:Value
函数mean
:
julia> @benchmark by($data, :Type, :Value => mean)
BenchmarkTools.Trial:
memory estimate: 15.27 MiB
allocs estimate: 190
--------------
minimum time: 8.326 ms (0.00% GC)
median time: 8.667 ms (0.00% GC)
mean time: 9.599 ms (2.74% GC)
maximum time: 17.364 ms (3.57% GC)
--------------
samples: 521
evals/sample: 1
Run Code Online (Sandbox Code Playgroud)
最后,让我们检查差异 if :Value
is a Vector{String}
(在另一个答案中给出的方法):
julia> data.Type = String.(data.Type);
julia> @benchmark by($data, [:Type], df -> mean(df[:, :Value]))
BenchmarkTools.Trial:
memory estimate: 46.16 MiB
allocs estimate: 197
--------------
minimum time: 26.664 ms (2.08% GC)
median time: 27.197 ms (2.11% GC)
mean time: 27.486 ms (2.11% GC)
maximum time: 35.740 ms (1.64% GC)
--------------
samples: 182
evals/sample: 1
Run Code Online (Sandbox Code Playgroud)
你可以看到它比推荐的答案慢了大约三倍。另请注意:
julia> by(data, :Type, :Value => mean)
2×2 DataFrame
? Row ? Type ? Value_mean ?
? ? String ? Float64 ?
?????????????????????????????
? 1 ? B ? 5.50175 ?
? 2 ? A ? 5.49524 ?
Run Code Online (Sandbox Code Playgroud)
为生成的列生成更好的默认名称(因为它知道源列名称和转换函数名称)。
归档时间: |
|
查看次数: |
465 次 |
最近记录: |