将数据组合成更小的离散间隔
Combine data into smaller discrete intervals
假设我们有一对输入数组,或者如果您愿意,可以有一个(键,值)元组列表。什么是将索引落在特定区间内的值组合起来的优雅且高效的方法?例如,如果间隔(或 'bin')大小为 10,则 0 < x <= 10
中所有索引的值将被合并,10 < x <= 20
中的索引值也会合并,依此类推。我要:
let interval = 10
let index = [| 6; 12; 18; 24 |]
let value = [| a; b; c; d |]
result = [| a; b + c; d |]
最粗暴的方法是使用大量的 if, else if 语句(索引范围有定义的上限)。我接近
for i = 0 to index.Length do
result.[Math.Floor(index.[i]/10] += value.[Math.Floor(index.[i]/10]
但这是在做 0 <= x < 10
,而不是 0 < x <= 10
。
我还尝试假设索引是有序且均匀分布的,
for i = 1 : ( index.Length - 1 ) / valuesPerBin
valueRange = ((i-1)*valuesPerBin + 1) : i*valuesPerBin )
result(i) = sum(value(valueRange))
这很好,但如果每个 bin 的值不是整数,显然会中断。
在 F# 中执行此操作的最佳方法是什么?有我想做的事情的名称或现有功能吗?
let interval = 10
let index = [6;12;18;24]
let value =[101;102;103;104]
let intervals = List.map (fun e -> e/interval) index
let keys = List.map2(fun e1 e2 -> (e1,e2)) intervals value
let skeys = Seq.ofList keys
let result = skeys
|>Seq.groupBy (fun p -> fst p)
|>Seq.map (fun p -> snd p)
|>Seq.map(fun s -> Seq.sumBy (fun p -> snd p) s)
result 将是 [101;205;104](作为 Seq) .
如果要转换为数组,应用Seq.toArray。
是你想要的吗?
适配周边代码使用
0 <= x < 10
而不是 0 < x <= 10
。在我的例子中,这只是另一个函数中的简单定义更改,允许我使用
for i = 0 to index.Length do
result.[Math.Floor(index.[i]/10] += value.[Math.Floor(index.[i]/10]
,这比替代方法更简单、更简洁。
假设我们有一对输入数组,或者如果您愿意,可以有一个(键,值)元组列表。什么是将索引落在特定区间内的值组合起来的优雅且高效的方法?例如,如果间隔(或 'bin')大小为 10,则 0 < x <= 10
中所有索引的值将被合并,10 < x <= 20
中的索引值也会合并,依此类推。我要:
let interval = 10
let index = [| 6; 12; 18; 24 |]
let value = [| a; b; c; d |]
result = [| a; b + c; d |]
最粗暴的方法是使用大量的 if, else if 语句(索引范围有定义的上限)。我接近
for i = 0 to index.Length do
result.[Math.Floor(index.[i]/10] += value.[Math.Floor(index.[i]/10]
但这是在做 0 <= x < 10
,而不是 0 < x <= 10
。
我还尝试假设索引是有序且均匀分布的,
for i = 1 : ( index.Length - 1 ) / valuesPerBin
valueRange = ((i-1)*valuesPerBin + 1) : i*valuesPerBin )
result(i) = sum(value(valueRange))
这很好,但如果每个 bin 的值不是整数,显然会中断。
在 F# 中执行此操作的最佳方法是什么?有我想做的事情的名称或现有功能吗?
let interval = 10
let index = [6;12;18;24]
let value =[101;102;103;104]
let intervals = List.map (fun e -> e/interval) index
let keys = List.map2(fun e1 e2 -> (e1,e2)) intervals value
let skeys = Seq.ofList keys
let result = skeys
|>Seq.groupBy (fun p -> fst p)
|>Seq.map (fun p -> snd p)
|>Seq.map(fun s -> Seq.sumBy (fun p -> snd p) s)
result 将是 [101;205;104](作为 Seq) .
如果要转换为数组,应用Seq.toArray。
是你想要的吗?
适配周边代码使用
0 <= x < 10
而不是 0 < x <= 10
。在我的例子中,这只是另一个函数中的简单定义更改,允许我使用
for i = 0 to index.Length do
result.[Math.Floor(index.[i]/10] += value.[Math.Floor(index.[i]/10]
,这比替代方法更简单、更简洁。