我正在将现有python代码转换为F#增加了太多的行数,不确定我是否做错了,或者有一个想要优化它的方法:
我Array想要处理这个:
let series = [|30;21;29;31;40;48;53;47;37;39;31;29;17;9;20;24;27;35;41;38;
27;31;27;26;21;13;21;18;33;35;40;36;22;24;21;20;17;14;17;19;
26;29;40;31;20;24;18;26;17;9;17;21;28;32;46;33;23;28;22;27;
18;8;17;21;31;34;44;38;31;30;26;32|]
Run Code Online (Sandbox Code Playgroud)
在Python它是:
series = [30,21,29,31,...,26,32]
Run Code Online (Sandbox Code Playgroud)
第1部分
在Python我这个:
def initial_seasonal_components(series, slen):
seasonals = {}
season_averages = []
n_seasons = int(len(series)/slen)
# compute season averages
for j in range(n_seasons):
season_averages.append(sum(series[slen*j:slen*j+slen])/float(slen))
Run Code Online (Sandbox Code Playgroud)
转换成F#我最终得到这个:
open System.Collections.Generic
let initial_seasonal_components (series : int []) (slen : int) : Dictionary<int, double> =
let seasonals = new Dictionary<int, double>()
let mutable seasonAverages = []
let nSeasons = series.Length / slen
// compute season averages
for i in 0 .. nSeasons-1 do
seasonAverages <-
series
|> Array.sub <|| (slen * i, slen)
|> Array.sum
|> float
|> fun s -> s / (slen |> float)
|> fun e -> [e]
|> List.append seasonAverages
Run Code Online (Sandbox Code Playgroud)
第2部分
在Python我这个:
for i in range(slen):
sum_of_vals_over_avg = 0.0
for j in range(n_seasons):
sum_of_vals_over_avg += series[slen*j+i]-season_averages[j]
seasonals[i] = sum_of_vals_over_avg/n_seasons
Run Code Online (Sandbox Code Playgroud)
转换成F#我最终得到这个:
for i in 0 .. slen-1 do
let mutable sumOfValsOverAvg = 0.0
for j in 0 .. nSeasons-1 do
sumOfValsOverAvg <-
series
|> Array.item (slen*j+i)
|> float
|> fun el -> el + sumOfValsOverAvg - seasonAverages.[j]
seasonals.Add (i, sumOfValsOverAvg / (nSeasons |> float))
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么,或者这是我能得到的优化代码!!
UPDATE
下面从全"Python`代码在这里:
series = [30,21,29,31,40,48,53,47,37,39,31,29,17,9,20,24,27,35,41,38,
27,31,27,26,21,13,21,18,33,35,40,36,22,24,21,20,17,14,17,19,
26,29,40,31,20,24,18,26,17,9,17,21,28,32,46,33,23,28,22,27,
18,8,17,21,31,34,44,38,31,30,26,32]
def initial_seasonal_components(series, slen):
seasonals = {}
season_averages = []
n_seasons = int(len(series)/slen)
# compute season averages
for j in range(n_seasons):
season_averages.append(sum(series[slen*j:slen*j+slen])/float(slen))
sarr = [str(a) for a in season_averages]
print(", " . join(sarr))
# compute initial values
for i in range(slen):
sum_of_vals_over_avg = 0.0
for j in range(n_seasons):
sum_of_vals_over_avg += series[slen*j+i]-season_averages[j]
seasonals[i] = sum_of_vals_over_avg/n_seasons
return seasonals
Run Code Online (Sandbox Code Playgroud)
在这里我的等效F#代码:
open System.Collections.Generic // for Dictionary
let series = [|30;21;29;31;40;48;53;47;37;39;31;29;17;9;20;24;27;35;41;38;
27;31;27;26;21;13;21;18;33;35;40;36;22;24;21;20;17;14;17;19;
26;29;40;31;20;24;18;26;17;9;17;21;28;32;46;33;23;28;22;27;
18;8;17;21;31;34;44;38;31;30;26;32|]
let initialAeasonalComponents (series : int []) slen : Dictionary<int, double> =
let seasonals = new Dictionary<int, double>()
let mutable seasonAverages = []
let nSeasons = series.Length / slen
// compute season averages
for i in 0 .. nSeasons-1 do
seasonAverages <-
series
|> Array.sub <|| (slen * i, slen)
|> Array.sum
|> float
|> fun s -> s / (slen |> float)
|> fun e -> [e]
|> List.append seasonAverages
printfn "Seasons Averageß: \n %A" seasonAverages
// compute initial values
for i in 0 .. slen-1 do
let mutable sumOfValsOverAvg = 0.0
for j in 0 .. nSeasons-1 do
sumOfValsOverAvg <-
series
|> Array.item (slen*j+i)
|> float
|> fun el -> el + sumOfValsOverAvg - seasonAverages.[j]
seasonals.Add (i, sumOfValsOverAvg / (nSeasons |> float))
printfn "Seasons Averageß: \n %A" seasonals
seasonals
initialAeasonalComponents series 12
Run Code Online (Sandbox Code Playgroud)
你需要以不同的方式思考,在F#中,mutability不是默认的.
对于第1部分,您可以这样做:
open System.Collections.Generic
let initial_seasonal_components (series : int []) (slen : int) =
let seasonals = new Dictionary<int, double>()
series |> Array.map float |> Array.chunkBySize slen |> Array.map Array.average
Run Code Online (Sandbox Code Playgroud)
对于第2部分,您还可以采用不同的方法:
[|0..slen-1|]
|> Array.map (fun i ->
i, Array.zip grouped seasonAverages
|> Array.fold (fun s (els, av) -> els.[i] + s - av) 0.)
|> Array.map (fun (i, x) -> i, x / float nSeasons)
|> dict
Run Code Online (Sandbox Code Playgroud)
结合所有部分,你可以像这样写:
let initialAeasonalComponents (series : int []) slen : IDictionary<int, double> =
let nSeasons = float (series.Length / slen)
let grouped = series |> Array.map float |> Array.chunkBySize slen
let seasonAverages = grouped |> Array.map Array.average
Array.init slen (fun i -> i, (Array.zip grouped seasonAverages
|> Array.fold (fun s (els, av) -> els.[i] + s - av) 0.)
/ nSeasons) |> dict
Run Code Online (Sandbox Code Playgroud)
请注意,与Python方法的主要区别在于我们使用更高阶函数,并且我们不使用可变性,这使得更容易推理代码.
还要注意,现在F#代码甚至比Python更短;)
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |