arrays - 在 Julia 中将一组数据帧转换为多维数组
问题描述
[一个朱莉娅菜鸟问题。]
假设我有一个数据帧向量,如下所示:
using DataFrames
A = DataFrame([8.1 9.2 7.5 6.6; 6.9 8.1 6.8 5.8])
B = DataFrame([9.0 2.1 5.2 5.3; 1.2 4.9 9.8 7.7])
dfs = [A, B]
当然,我实际上有dfs
比这个 MWE 更多的数据框,但是它们都具有相同的维度,并且它们都只有数字列。
我想转换dfs
成一个多维(这里是 2x4x2)数组arr
,arr[:, :, 1]
等于 A,arr[:, :, 2]
等于 B。我该如何执行这个转换?(当然,for
循环可能会解决问题,但我想还有一种更优雅的方式来进行。)
谢谢!
解决方案
我想
f1(dfs) = cat(Matrix.(dfs)..., dims=3)
是一个相当优雅的单线,但它分配临时。
从速度的角度来看,您可能可以使用以下单线轻松击败它
f2(dfs) = [ dfs[k][n,m] for n = 1:size(dfs[1],1), m = 1:size(dfs[1],2), k = 1:length(dfs) ]
话虽如此,如果您愿意更详细一点,您可能可以再次使用专门设计用于与DataFrame
.
function f3(dfs)
y = Array{Float64,3}(undef, size(dfs[1],1), size(dfs[1],2), length(dfs))
for k = 1:length(dfs) ; for (n,col) in enumerate(eachcol(dfs[k]))
y[:,n,k] = col
end ; end
return y
end
一般来说,如果你想要 Julia 的速度,循环通常是最好的方法。让我们快速比较一下这三种方法:
julia> using BenchmarkTools
julia> @btime f1($dfs);
182.454 μs (132 allocations: 7.89 KiB)
julia> @btime f2($dfs);
935.217 ns (21 allocations: 672 bytes)
julia> @btime f3($dfs);
338.664 ns (11 allocations: 368 bytes)
所以比 .f3
快 6 倍f1
。您可以投入@inbounds
并f2
进行f3
进一步优化,尽管我怀疑它不会为您带来太多好处...
现在,公平地说,我只是假设一切都在Float64
这里。但是,通过预先进行快速类型检查,您可以将其推广到任何类型(只要它都是一种类型 - 大概是因为您想要转换为单个数组)。
推荐阅读
- azure - 如果 Azure 逻辑应用中的 Scope 操作中的任何操作失败,如何捕获异常详细信息
- xamarin - xamarin 中的跟踪器布局
- android - android ContactsContract中的地址字段在哪里
- pulumi - 将同名文件写入两个 S3 存储桶时出现错误“错误:重复资源 URN”
- c++ - 将函数引用传递给模板警告:忽略模板参数“func signature”上的属性
- locust - 为什么剂量蝗虫一段时间后不发送请求?我该如何解决?
- vim - 在vim中保持光标线垂直居中
- google-cloud-dataflow - 数据流不缩放
- ag-grid - ag-grid safari 列移动和 enableCellTextSelection
- node.js - Dynamodb.put 在运行 lambda 测试配置时工作正常,但在通过 API 网关调用 lambda 时却不行