From 44365111b46192aba25c2681f4b9a68d97781275 Mon Sep 17 00:00:00 2001 From: Matt Thornton Date: Fri, 18 Nov 2022 16:55:26 +0000 Subject: [PATCH] Propagate missing values in Stats.cov from Stats.stdDev. (#552) --- src/Deedle.Math/Stats.fs | 2 +- tests/Deedle.Math.Tests/Stats.fs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Deedle.Math/Stats.fs b/src/Deedle.Math/Stats.fs index 90647a3e..d44be5f6 100644 --- a/src/Deedle.Math/Stats.fs +++ b/src/Deedle.Math/Stats.fs @@ -140,7 +140,7 @@ type Stats = static member covMatrix (df:Frame<'R, 'C>) = // Treat nan as zero, the same as MATLAB let corr = Stats.corrMatrix(df) |> Matrix.map(fun x -> if Double.IsNaN x then 0. else x) - let stdev = df |> Stats.stdDev |> Series.values |> Array.ofSeq + let stdev = df |> Stats.stdDev |> Series.valuesAll |> Seq.map (Option.defaultValue nan) |> Array.ofSeq let stdevDiag = DenseMatrix.ofDiagArray stdev stdevDiag * corr * stdevDiag diff --git a/tests/Deedle.Math.Tests/Stats.fs b/tests/Deedle.Math.Tests/Stats.fs index b705122a..963106bf 100644 --- a/tests/Deedle.Math.Tests/Stats.fs +++ b/tests/Deedle.Math.Tests/Stats.fs @@ -66,3 +66,22 @@ let ``cov2Corr and corr2Cov work`` () = let actual = Stats.corr2Cov(std, corr).GetColumnAt(0).GetAt(0) let expected = cov.GetColumnAt(0).GetAt(0) actual |> should beWithin (expected +/- 1e-6) + +[] +let ``cov propogates missing values when stddev produces missing values`` () = + let returns = + Frame.ofColumns [ "A" + => series [ DateTime(2022, 11, 1) => 0. + DateTime(2022, 11, 2) => 0. ] + "B" => series [ DateTime(2022, 11, 1) => 0. ] ] + + let cov = returns |> Stats.cov + + let expected = + Frame.ofRowKeys [ "A"; "B" ] + |> Frame.addCol "A" (series [ "A" => 0. ]) + |> Frame.addCol "B" (series []) + + cov + |> Frame.toMatrix + |> shouldEqual (expected |> Frame.toMatrix)