我从如下所示的 csv 文件中解析数据:
X,..,..,Dx,..,..
Y,..,..,Dy,..,..
X,..,..,Dx,..,..
Y,..,..,Dy,..,..
X,..,..,Dx,..,..
Y,..,..,Dy,..,..
每一行都是我定义的类型数组的一个元素,并与 FileHelpers 一起使用。这可能不相关,但我将这个包括在内,以防有人知道我可以在这个阶段使用 FileHelpers 做的一个技巧。
我只对 X,Dx 和 Y,Dy 对感兴趣 数据可能不仅仅是 X 和 Y 例如.. (X,Dx); (Y,Dy); (Z,Dz); ...
我将字母的数量称为 nL
目标是通过处理具有 SUM(nIterations) * nL 元素的所有 D 的数组来获得每个组的 Dx、Dy、... 的平均值。
我有一个迭代次数列表:
let nIterations = [2000; 2000; 2000; 1000; 500; 400; 400; 400; 300; 300]
对于这些数字中的每一个,我都会有那么多“字母组”。因此,nIterations.[0] 感兴趣的数据行是第 0 行到 (nIterations.[0] * nL)
为了获得 nIterations.[i] 感兴趣的行,我创建了一个列表“nis”,它是对 nIterations 执行的扫描操作的结果。
let nis = List.scan (fun x e -> x + e) 0 nIterations
然后隔离 nItertions.[i] 组..
let group = Array.sub Ds (nis.[i]*nL) (nIterations.[i]*nL)
这是整个事情:
nIterations |> List.mapi (fun i ni ->
let igroup = Array.sub Ds (nis.[i]*nL) (ni*nL)
let groupedbyLetter = (chunk nL igroup)
let sums = seq { for idx in 0..(nL - 1) do
let d = seq { for g in groupedbyLetter do
yield (Seq.head (Seq.skip idx g)) }
yield d |> Seq.sum }
sums |> Seq.map (fun x -> (x / (float ni))) ) |> List.ofSeq
“块”功能是我在 SO 上找到的功能:
let rec chunk n xs =
if Seq.isEmpty xs then Seq.empty
else
let (ys,zs) = splitAt n xs
Seq.append (Seq.singleton ys) (chunk n zs)
我已经验证了这项工作,并得到了我想要的 - 一个大小为 nL 的集合,大小为 nIterations.Length 集合。
问题是速度——这只适用于小数据集;我在给出的示例中使用的尺寸太大了。它在块函数中“挂起”。
所以我的问题是:我该如何提高整个过程的速度?(和/或)进行“换位”的最佳(或至少更好)方法是什么
我想我可以:
- 尝试在我读取数据时重新排列数据
- 尝试直接索引元素
- 尝试将过程分解为更小的阶段或“通过”
- ???