我在 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 │
如何根据列 类型 获得列 值 的平均值?
最佳答案
如果您想要性能,请考虑以下选项
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)));
请注意,我将
: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
这是我将
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
这是一种有效的编写方法。此语句意味着我们将列
: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
最后,让我们检查一下
:Value
是否是 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
你可以看到它比推荐的答案慢了大约三倍。另请注意:
julia> by(data, :Type, :Value => mean)
2×2 DataFrame
│ Row │ Type │ Value_mean │
│ │ String │ Float64 │
├─────┼────────┼────────────┤
│ 1 │ B │ 5.50175 │
│ 2 │ A │ 5.49524 │
为生成的列生成更好的默认名称(因为它知道源列名称和转换函数名称)。
关于julia - 如何根据Julia中列中的值查找数据框行的平均值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60821416/