Logo Deedle

Deedle.MathNetNumerics — MathNet.Numerics integration

Deedle.MathNetNumerics is a separate NuGet package that extends Deedle with linear algebra, advanced statistics, PCA, and financial time-series functions via the MathNet.Numerics library.

Installation

dotnet add package Deedle.MathNetNumerics

Then reference in F# script or notebook:

#r "nuget: Deedle"
#r "nuget: Deedle.MathNetNumerics"
#r "nuget: MathNet.Numerics"
#r "nuget: MathNet.Numerics.FSharp"

open Deedle
open Deedle.MathNetNumerics

Frame and Series ↔ Matrix conversions

Deedle.MathNetNumerics adds a Frame type alias and a Series type alias in the Deedle.MathNetNumerics namespace that provide toMatrix / ofMatrix and toVector / ofVector helpers. Opening Deedle.MathNetNumerics after Deedle makes these available without qualifying.

// Build a simple 3×3 frame
let df =
  frame [ "A" => series [ 1 => 1.0; 2 => 4.0; 3 => 7.0 ]
          "B" => series [ 1 => 2.0; 2 => 5.0; 3 => 8.0 ]
          "C" => series [ 1 => 3.0; 2 => 6.0; 3 => 9.0 ] ]

// Convert frame to a MathNet DenseMatrix
let m : Matrix<float> = Frame.toMatrix df
m
val df: Frame<int,string> = 
     A B C 
1 -> 1 2 3 
2 -> 4 5 6 
3 -> 7 8 9 

val m: Matrix<float> = DenseMatrix 3x3-Double
1  2  3
4  5  6
7  8  9

val it: Matrix<float> = DenseMatrix 3x3-Double
1  2  3
4  5  6
7  8  9
// Convert matrix back to a frame with named rows and columns
Frame.ofMatrix [1;2;3] ["A";"B";"C"] m
val it: Frame<int,string> = 
     A B C 
1 -> 1 2 3 
2 -> 4 5 6 
3 -> 7 8 9

Series ↔ Vector works the same way:

let s = series [ "x" => 1.0; "y" => 2.0; "z" => 3.0 ]
let v : Vector<float> = Series.toVector s
v
val s: Series<string,float> = 
x -> 1 
y -> 2 
z -> 3 

val v: Vector<float>
val it: Vector<float>
Series.ofVector ["x";"y";"z"] v
val it: Series<string,float> = 
x -> 1 
y -> 2 
z -> 3

There is also a Matrix type with explicit ofFrame / toFrame helpers and dot-product overloads that let you multiply frames, series, and vectors directly:

// Frame × Frame matrix multiply (column keys of left must equal row keys of right)
Matrix.dot df df

// Frame × Vector
Matrix.dot df v

// Series (as row vector) × Frame
Matrix.dot s df

Linear algebra on frames

LinearAlgebra provides matrix operations that accept and return Frame<'R,'C> values directly. All operations convert to/from Matrix<float> internally.

// Transpose (faster than generic Frame.transpose for numeric frames)
LinearAlgebra.transpose df
val it: Frame<string,int> = 
     1 2 3 
A -> 1 4 7 
B -> 2 5 8 
C -> 3 6 9
// Matrix inverse
let sq = frame [ "A" => series [1=>4.0;2=>7.0]; "B" => series [1=>3.0;2=>6.0] ]
LinearAlgebra.inverse sq
val sq: Frame<int,string> = 
     A B 
1 -> 4 3 
2 -> 7 6 

val it: Matrix<float> =
  DenseMatrix 2x2-Double
       2       -1
-2.33333  1.33333

Other available operations:

Function

Description

LinearAlgebra.pseudoInverse df

Moore–Penrose pseudo-inverse

LinearAlgebra.determinant df

Scalar determinant

LinearAlgebra.trace df

Scalar trace

LinearAlgebra.rank df

Integer rank

LinearAlgebra.norm df

Frobenius norm (float)

LinearAlgebra.normRows df

Vector of row norms

LinearAlgebra.normCols df

Vector of column norms

LinearAlgebra.condition df

Condition number

LinearAlgebra.nullity df

Nullity

LinearAlgebra.kernel df

Kernel (null space)

LinearAlgebra.isSymmetric df

Boolean symmetry test

LinearAlgebra.cholesky df

Cholesky decomposition

LinearAlgebra.lu df

LU decomposition

LinearAlgebra.qr df

QR decomposition

LinearAlgebra.svd df

SVD decomposition

LinearAlgebra.eigen df

Eigenvalues and eigenvectors


Descriptive statistics

Deedle.MathNetNumerics.Stats extends the base Deedle.Stats with richer descriptive statistics from MathNet.Numerics.

let air = Frame.ReadCsv(root + "airquality.csv", separators=";")
let ozone = air?Ozone |> Series.dropMissing

// Median (uses MathNet's exact median algorithm)
Stats.median ozone
val air: Frame<int,string> =
  
       Ozone     Solar.R   Wind Temp Month Day 
0   -> <missing> 190       7.4  67   5     1   
1   -> 36        118       8    72   5     2   
2   -> 12        149       12.6 74   5     3   
3   -> 18        313       11.5 62   5     4   
4   -> <missing> <missing> 14.3 56   5     5   
5   -> 28        <missing> 14.9 66   5     6   
6   -> 23        299       8.6  65   5     7   
7   -> 19        99        13.8 59   5     8   
8   -> 8         19        20.1 61   5     9   
9   -> <missing> 194       8.6  69   5     10  
10  -> 7         <missing> 6.9  74   5     11  
11  -> 16        256       9.7  69   5     12  
12  -> 11        290       9.2  66   5     13  
13  -> 14        274       10.9 68   5     14  
14  -> 18        65        13.2 58   5     15  
:      ...       ...       ...  ...  ...   ... 
138 -> 46        237       6.9  78   9     16  
139 -> 18        224       13.8 67   9     17  
140 -> 13        27        10.3 76   9     18  
141 -> 24        238       10.3 68   9     19  
142 -> 16        201       8    82   9     20  
143 -> 13        238       12.6 64   9     21  
144 -> 23        14        9.2  71   9     22  
145 -> 36        139       10.3 81   9     23  
146 -> 7         49        10.3 69   9     24  
147 -> 14        20        16.6 63   9     25  
148 -> 30        193       6.9  70   9     26  
149 -> <missing> 145       13.2 77   9     27  
150 -> 14        191       14.3 75   9     28  
151 -> 18        131       8    76   9     29  
152 -> 20        223       11.5 68   9     30  

val ozone: Series<int,float> =
  
1   -> 36  
2   -> 12  
3   -> 18  
5   -> 28  
6   -> 23  
7   -> 19  
8   -> 8   
10  -> 7   
11  -> 16  
12  -> 11  
13  -> 14  
14  -> 18  
15  -> 14  
16  -> 34  
17  -> 6   
... -> ... 
137 -> 13  
138 -> 46  
139 -> 18  
140 -> 13  
141 -> 24  
142 -> 16  
143 -> 13  
144 -> 23  
145 -> 36  
146 -> 7   
147 -> 14  
148 -> 30  
150 -> 14  
151 -> 18  
152 -> 20  

val it: float = 31.0
// 25th and 75th percentile
Stats.quantile(ozone, 0.25), Stats.quantile(ozone, 0.75)
val it: float * float = (18.0, 63.5)
// Ranks (average rank for ties by default)
ozone |> Stats.ranks |> Series.take 6
val it: Series<int,float> =
  
1 -> 65.5 
2 -> 15.5 
3 -> 30.5 
5 -> 53   
6 -> 45.5 
7 -> 33

All three functions also work on entire frames:

// Median of each numeric column
Stats.median air

// 90th percentile of each numeric column
Stats.quantile(air, 0.90)

Correlation and covariance

// Use a small subset of air quality numeric columns
let numAir = air |> Frame.sliceCols ["Ozone";"Solar.R";"Wind";"Temp"] |> Frame.dropSparseRows

// Pearson correlation matrix (default)
Stats.corr numAir
val numAir: Frame<int,string> =
  
       Ozone Solar.R Wind Temp 
1   -> 36    118     8    72   
2   -> 12    149     12.6 74   
3   -> 18    313     11.5 62   
6   -> 23    299     8.6  65   
7   -> 19    99      13.8 59   
8   -> 8     19      20.1 61   
11  -> 16    256     9.7  69   
12  -> 11    290     9.2  66   
13  -> 14    274     10.9 68   
14  -> 18    65      13.2 58   
15  -> 14    334     11.5 64   
16  -> 34    307     12   66   
17  -> 6     78      18.4 57   
18  -> 30    322     11.5 68   
19  -> 11    44      9.7  62   
:      ...   ...     ...  ...  
137 -> 13    112     11.5 71   
138 -> 46    237     6.9  78   
139 -> 18    224     13.8 67   
140 -> 13    27      10.3 76   
141 -> 24    238     10.3 68   
142 -> 16    201     8    82   
143 -> 13    238     12.6 64   
144 -> 23    14      9.2  71   
145 -> 36    139     10.3 81   
146 -> 7     49      10.3 69   
147 -> 14    20      16.6 63   
148 -> 30    193     6.9  70   
150 -> 14    191     14.3 75   
151 -> 18    131     8    76   
152 -> 20    223     11.5 68   

val it: Frame<string,string> =
  
           Ozone               Solar.R              Wind                 Temp                
Ozone   -> 1                   0.34836591218820606  -0.6141530630103393  0.7023458156557731  
Solar.R -> 0.34836591218820606 1                    -0.12710934002770172 0.2964335602155499  
Wind    -> -0.6141530630103393 -0.12710934002770172 1                    -0.5087914965402979 
Temp    -> 0.7023458156557731  0.2964335602155499   -0.5087914965402979  1
// Spearman rank correlation
Stats.corr(numAir, CorrelationMethod.Spearman)
val it: Frame<string,string> =
  
           Ozone               Solar.R              Wind                 Temp                
Ozone   -> 1                   0.35053386000742803  -0.6027870894327034  0.7827104662215925  
Solar.R -> 0.35053386000742803 1                    -0.06377856427131096 0.20782359283634763 
Wind    -> -0.6027870894327034 -0.06377856427131096 1                    -0.5129716950336768 
Temp    -> 0.7827104662215925  0.20782359283634763  -0.5129716950336768  1
// Covariance frame
Stats.cov numAir
val it: Frame<string,string> =
  
           Ozone              Solar.R            Wind               Temp               
Ozone   -> 1117.4375312760633 1066.3297748123437 -73.20231859883299 223.44320266889065 
Solar.R -> 1066.3297748123437 8384.719015846538  -41.50097581317802 258.3307756463719  
Wind    -> -73.20231859883299 -41.50097581317802 12.71373561301105  -17.26557130942466 
Temp    -> 223.44320266889068 258.3307756463719  -17.26557130942466 90.57514595496245

To correlate two individual series:

Stats.corr(air?Ozone, air?Temp)

Converting between correlation and covariance

Stats.cov2Corr decomposes a covariance matrix into a standard-deviation series and a correlation frame; Stats.corr2Cov inverts that operation:

let stdDevs, corrFrame = Stats.cov2Corr (Stats.cov numAir)
let recoveredCov       = Stats.corr2Cov(stdDevs, corrFrame)

Exponentially weighted moving statistics

The Stats and Finance types provide a full suite of exponentially weighted moving (EWM) statistics. The decay rate can be specified via one of four mutually exclusive parameters:

Parameter

Meaning

com

Center of mass — α = 1 / (1 + com), com ≥ 0

span

Span — α = 2 / (span + 1), span ≥ 1

halfLife

Half-life — α = 1 − exp(ln(0.5)/halfLife), halfLife > 0

alpha

Direct smoothing factor — 0 < α ≤ 1

// Sample daily returns series
let returns =
  series [ for i in 1..20 -> i => Math.Sin(float i * 0.3) * 0.02 ]

// EWM mean with span=5
Stats.ewmMean(returns, span=5.0)
val returns: Series<int,float> =
  
1  -> 0.005910404133226791   
2  -> 0.011292849467900708   
3  -> 0.015666538192549668   
4  -> 0.018640781719344527   
5  -> 0.01994989973208109    
6  -> 0.019476952617563905   
7  -> 0.017264187332977476   
8  -> 0.01350926361102302    
9  -> 0.008547597604676603   
10 -> 0.002822400161197344   
11 -> -0.0031549138828649644 
12 -> -0.008850408865897042  
13 -> -0.013755323183679476  
14 -> -0.017431515448271765  
15 -> -0.01955060235330194   
16 -> -0.019923292176716813  
17 -> -0.01851629364655465   
18 -> -0.015455289751119754  
19 -> -0.011013710851952753  
20 -> -0.005588309963978517  

val it: Series<int,float> =
  
1  -> 0.005910404133226791  
2  -> 0.007704552578118098  
3  -> 0.01035854778292862   
4  -> 0.01311929242840059   
5  -> 0.015396161529627424  
6  -> 0.01675642522560625   
7  -> 0.01692567926139666   
8  -> 0.015786874044605447  
9  -> 0.013373781897962499  
10 -> 0.009856654652374114  
11 -> 0.005519465140627755  
12 -> 0.0007295071384528238 
13 -> -0.004098769635591276 
14 -> -0.008543018239818106 
15 -> -0.012212212944312718 
16 -> -0.014782572688447418 
17 -> -0.01602714634114983  
18 -> -0.01583652747780647  
19 -> -0.014228921935855232 
20 -> -0.011348717945229661
// EWM mean on a whole frame (applied column by column)
Stats.ewmMean(numAir, span=10.0)
val it: Frame<int,string> =
  
       Ozone              Solar.R            Wind               Temp               
1   -> 36                 118                8                  72                 
2   -> 31.636363636363633 123.63636363636363 8.836363636363636  72.36363636363636  
3   -> 29.157024793388427 158.06611570247932 9.320661157024793  70.47933884297521  
6   -> 28.037565740045075 183.69045830202853 9.189631855747557  69.48309541697971  
7   -> 26.394371969127786 168.29219315620514 10.027880609248001 67.57707806843794  
8   -> 23.04994070201364  141.14815803689513 11.859175043930183 66.3812456923583   
11  -> 21.768133301647524 162.03031112109602 11.466597763215603 66.85738283920224  
12  -> 19.810290883166154 185.29752728089673 11.054489078994584 66.70149505025637  
13  -> 18.753874358954125 201.42524959346093 11.026400155541022 66.93758685930067  
14  -> 18.616806293689738 176.6206587582862  11.421600127260836 65.31257106670054  
15  -> 17.77738696756433  205.23508443859777 11.435854649577045 65.0739217818459   
16  -> 20.72695297346172  223.7377963588527  11.538426531472128 65.24229963969209  
17  -> 18.04932516010504  197.24001520269766 12.78598534393174  63.743699705202616 
18  -> 20.222175130995033 219.92364880220714 12.552169826853241 64.51757248607487  
19  -> 18.545416016268664 187.93753083816947 12.033593494698106 64.05983203406126  
:      ...                ...                ...                ...                
137 -> 28.35087017123703  172.93674754861382 10.62939356863658  76.97098060271549  
138 -> 31.55980286737575  184.58461163068404 9.951322010702656  77.1580750385854   
139 -> 29.09438416421652  191.75104587965055 10.651081645120355 75.31115230429714  
140 -> 26.168132497995334 161.79631026516861 10.587248618734835 75.43639733987948  
141 -> 25.773926589268907 175.6515265805925  10.535021597146683 74.08432509626502  
142 -> 23.99684902758365  180.26033992957565 10.07410857948365  75.52353871512592  
143 -> 21.99742193165935  190.75845994238009 10.533361565032076 73.4283498578303   
144 -> 22.179708853175832 158.62055813467458 10.290932189571697 72.98683170186115  
145 -> 24.69248906168932  155.05318392837012 10.292580882376843 74.44377139243184  
146 -> 21.475672868654897 135.77078685048463 10.29392981285378  73.45399477562604  
147 -> 20.116459619808552 114.72155287766924 11.440488028698546 71.55326845278495  
148 -> 21.91346696166154  128.9539978090021  10.614944750753354 71.27085600682405  
150 -> 20.47465478681399  140.23508911645624 11.284954796070926 71.9488821874015   
151 -> 20.024717552847807 138.55598200437328 10.687690287694393 72.6854490624194   
152 -> 20.020223452330022 153.90943982175995 10.835382962659047 71.83354923288859

Moving statistics on frames

Stats.movingStdDevParallel, Stats.movingVarianceParallel, and Stats.movingCovarianceParallel compute rolling window standard deviation, variance, and covariance matrices over a frame using parallel evaluation:

// Rolling 10-day standard deviation of each column
let rollingStd = Stats.movingStdDevParallel 10 numAir

// Rolling 10-day covariance matrix (returns Series<rowKey, Matrix<float>>)
let rollingCov = Stats.movingCovarianceParallel 10 numAir

Financial time-series: EWM volatility and covariance

Finance (in Deedle.MathNetNumerics) provides exponentially weighted volatility and covariance functions that are common in quantitative finance.

let prices =
  series [ for i in 1..30 -> i => 100.0 * Math.Exp(Math.Sin(float i * 0.2) * 0.1) ]

let dailyReturns = prices.Diff(1) / prices.Shift(1)

// Mean-corrected EWM volatility (standard deviation form) with half-life of 10 days
Finance.ewmVolStdDev(dailyReturns, halfLife=10.0)
val prices: Series<int,float> =
  
1  -> 102.00655940080074 
2  -> 103.97100063591236 
3  -> 105.80887846348735 
4  -> 107.43712525166751 
5  -> 108.77888941343824 
6  -> 109.76855399675529 
7  -> 110.35640338624115 
8  -> 110.51237949285047 
9  -> 110.22844103923283 
10 -> 109.51920572994001 
11 -> 108.420786323006   
12 -> 106.98798132024343 
13 -> 105.29019745068742 
14 -> 103.40662183732053 
15 -> 101.4212045143998  
16 -> 99.41795902566265  
17 -> 97.47696325563075  
18 -> 95.67127930478267  
19 -> 94.06484613148905  
20 -> 92.71126038603612  
21 -> 91.65326595654231  
22 -> 90.92272578743619  
23 -> 90.54084597502928  
24 -> 90.51845251400941  
25 -> 90.85617471011706  
26 -> 91.54445675083369  
27 -> 92.56339278854479  
28 -> 93.88245510845117  
29 -> 95.46025358686424  
30 -> 97.24452047374984  

val dailyReturns: Series<int,float> =
  
2  -> 0.019257989355302194   
3  -> 0.017676831196526625   
4  -> 0.01538856485225898    
5  -> 0.012488831571281276   
6  -> 0.009097947116885996   
7  -> 0.005355353314604513   
8  -> 0.0014133851940010078  
9  -> -0.0025692909239729655 
10 -> -0.0064342315159876835 
11 -> -0.010029468344050737  
12 -> -0.01321522423286958   
13 -> -0.01586892143028759   
14 -> -0.017889372980320013  
15 -> -0.019200098481547793  
16 -> -0.019751742235054295  
17 -> -0.019523593011307714  
18 -> -0.01852421218860419   
19 -> -0.016791174791088187  
20 -> -0.01438992143314427   
21 -> -0.01141171444642721   
22 -> -0.007970694349861014  
23 -> -0.004200047997897531  
24 -> -0.0002473299291465638 
25 -> 0.003730976245482984   
26 -> 0.0075755119881795695  
27 -> 0.011130505045045458   
28 -> 0.014250367020574686   
29 -> 0.016806105854288007   
30 -> 0.018691202043183416   

val it: Series<int,float> =
  
2  -> 0.013664333631420325 
3  -> 0.013205217009834477 
4  -> 0.012792526547233599 
5  -> 0.012467649357350036 
6  -> 0.012284777733702706 
7  -> 0.012298472040201569 
8  -> 0.012546187598639522 
9  -> 0.013033195668680301 
10 -> 0.013728112366462469 
11 -> 0.014570624960344116 
12 -> 0.015485400930932995 
13 -> 0.016395099994245498 
14 -> 0.01722929430909024  
15 -> 0.01792954535585723  
16 -> 0.018452016095533576 
17 -> 0.018768775418971387 
18 -> 0.01886844414807086  
19 -> 0.018756439444258043 
20 -> 0.01845481680718146  
21 -> 0.018001503423977678 
22 -> 0.017448491542290185 
23 -> 0.016858308794847145 
24 -> 0.01629794423197617  
25 -> 0.015829762026497888 
26 -> 0.015500257687858511 
27 -> 0.015329668408967484 
28 -> 0.015306847494267814 
29 -> 0.015392334479554334 
30 -> 0.015528537839504815

Finance.ewmVolRMS computes the same quantity using root-mean-square (no mean correction), which is appropriate for already-centred return series:

Finance.ewmVolRMS(dailyReturns, span=20.0)

Note: the older Finance.ewmVol is deprecated. Use ewmVolStdDev or ewmVolRMS depending on whether you want mean correction.

EWM variance

// Scalar EWM variance per time step
Finance.ewmVar(dailyReturns, com=5.0)

EWM covariance and correlation on frames

// Returns Series<rowKey, Frame<colKey,colKey>> — one covariance frame per row
let ewmCovFrames = Finance.ewmCov(numAir, span=20.0)

// Returns Series<rowKey, Frame<colKey,colKey>> — one correlation frame per row
let ewmCorrFrames = Finance.ewmCorr(numAir, span=20.0)

Principal Component Analysis (PCA)

The PCA module provides a simple API for principal component analysis. It normalises the columns by z-score internally and returns a record containing the eigen values and eigen vectors in descending order of explained variance.

// Use the numeric air quality columns
let normed = PCA.normalizeColumns numAir

let result = PCA.pca numAir
// Eigen values (proportion of variance explained by each PC)
result.EigenValues
val normed: Frame<int,string> =
  
       Ozone                Solar.R              Wind                 Temp                 
1   -> -0.18275318770542529 -0.7290152048765213  -0.5504569624217873  -0.6189816857657777  
2   -> -0.9007121394053104  -0.39046939953416293 0.73963670587569     -0.4088335825736927  
3   -> -0.7212224014803391  1.400547119051217    0.4311360460654237   -1.669722201726203   
6   -> -0.5716476198761964  1.247655465025636    -0.3821838752525512  -1.3545000469380752  
7   -> -0.6913074451595106  -0.9365110210540958  1.0761828802141626   -1.9849443565143305  
8   -> -1.0203719646886245  -1.8101776154859885  2.8430502954911425   -1.7747962533222454  
11  -> -0.7810523141219962  0.7780596705184936   -0.073683215442285   -0.9342038405539053  
12  -> -0.9306270957261389  1.1493679731520479   -0.21391078808331512 -1.2494259953420328  
13  -> -0.8408822267636533  0.9746346542656694   0.26286295889618766  -1.0392778921499477  
14  -> -0.7212224014803391  -1.3078193236876503  0.907909793044926    -2.0900184081103728  
15  -> -0.8408822267636533  1.629884600089589    0.4311360460654237   -1.459574098534118   
16  -> -0.2425831003470824  1.3350221244688252   0.5713636187064538   -1.2494259953420328  
17  -> -1.0802018773302817  -1.1658485020924676  2.3662765485116393   -2.1950924597064154  
18  -> -0.36224292563039656 1.498834610924805    0.4311360460654237   -1.0392778921499477  
19  -> -0.9306270957261389  -1.537156804726022   -0.073683215442285   -1.669722201726203   
:      ...                  ...                  ...                  ...                  
137 -> -0.8707971830844818  -0.7945401994589133  0.4311360460654237   -0.7240557373618203  
138 -> 0.11639637550286015  0.570563854340919    -0.8589576222320535  0.011462623810477393 
139 -> -0.7212224014803391  0.4285930327457365   1.0761828802141626   -1.1443519437459904  
140 -> -0.8707971830844818  -1.7228109560427993  0.09458987172695157  -0.19868547938160763 
141 -> -0.5417326635553679  0.5814846867713177   0.09458987172695157  -1.0392778921499477  
142 -> -0.7810523141219962  0.17741388684656734  -0.5504569624217873  0.43175883019464745  
143 -> -0.8707971830844818  0.5814846867713177   0.73963670587569     -1.459574098534118   
144 -> -0.5716476198761964  -1.8647817776379818  -0.21391078808331512 -0.7240557373618203  
145 -> -0.18275318770542529 -0.4996777238381495  0.09458987172695157  0.32668477859860495  
146 -> -1.050286921009453   -1.4825526425740287  0.09458987172695157  -0.9342038405539053  
147 -> -0.8408822267636533  -1.79925678305559    1.8614572870039316   -1.5646481501301603  
148 -> -0.36224292563039656 0.09004722740337807  -0.8589576222320535  -0.8291297889578627  
150 -> -0.8408822267636533  0.06820556254258076  1.2164104528551927   -0.3037595309776502  
151 -> -0.7212224014803391  -0.5870443832813388  -0.5504569624217873  -0.19868547938160763 
152 -> -0.661392488838682   0.41767220031533786  0.4311360460654237   -1.0392778921499477  

val result: PCA.t<string> =
  { EigenVectors =
     
           PC1                   PC2                 PC3                 PC4                  
Ozone   -> -0.14302573845191544  -0.96711437980886   0.20286001687822686 0.05550881064636915  
Solar.R -> -0.9891158377073584   0.14700234921163152 0.00463025073308681 -0.00432778244380515 
Wind    -> 0.0061047618879213165 0.06855028063392826 0.05859960622971001 0.9959064599936202   
Temp    -> -0.03400337658302009  -0.1959105528505185 -0.9774417939089967 0.07120649677325888  

    EigenValues =
     
PC1 -> 8548.046777408817  
PC2 -> 1005.8064115893684 
PC3 -> 44.012708445536944 
PC4 -> 7.5795312468514755 
 }
val it: Series<string,float> =
  
PC1 -> 8548.046777408817  
PC2 -> 1005.8064115893684 
PC3 -> 44.012708445536944 
PC4 -> 7.5795312468514755
// Eigen vectors (loadings): rows = original variables, columns = PC1, PC2, …
result.EigenVectors
val it: Frame<string,string> =
  
           PC1                   PC2                 PC3                 PC4                  
Ozone   -> -0.14302573845191544  -0.96711437980886   0.20286001687822686 0.05550881064636915  
Solar.R -> -0.9891158377073584   0.14700234921163152 0.00463025073308681 -0.00432778244380515 
Wind    -> 0.0061047618879213165 0.06855028063392826 0.05859960622971001 0.9959064599936202   
Temp    -> -0.03400337658302009  -0.1959105528505185 -0.9774417939089967 0.07120649677325888

Access the fields via the helper functions PCA.eigenValues and PCA.eigenVectors:

let ev = PCA.eigenValues  result   // Series<string, float>
let vecs = PCA.eigenVectors result  // Frame<colKey, string>

Linear regression

LinearRegression.ols fits an ordinary-least-squares model from columns in a frame:

open Deedle.MathNetNumerics

// Fit: Ozone ~ Solar.R + Wind + Temp (with intercept)
let fit = LinearRegression.ols ["Solar.R"; "Wind"; "Temp"] "Ozone" true numAir

The returned Fit.t record provides:

let fit = LinearRegression.ols ["Solar.R"; "Wind"; "Temp"] "Ozone" true numAir

// Regression coefficients (Intercept, Solar.R, Wind, Temp)
LinearRegression.Fit.coefficients fit
val fit: LinearRegression.Fit.t<int> =
  { InputFrame =
     
       Ozone Solar.R Wind Temp 
1   -> 36    118     8    72   
2   -> 12    149     12.6 74   
3   -> 18    313     11.5 62   
6   -> 23    299     8.6  65   
7   -> 19    99      13.8 59   
8   -> 8     19      20.1 61   
11  -> 16    256     9.7  69   
12  -> 11    290     9.2  66   
13  -> 14    274     10.9 68   
14  -> 18    65      13.2 58   
15  -> 14    334     11.5 64   
16  -> 34    307     12   66   
17  -> 6     78      18.4 57   
18  -> 30    322     11.5 68   
19  -> 11    44      9.7  62   
:      ...   ...     ...  ...  
137 -> 13    112     11.5 71   
138 -> 46    237     6.9  78   
139 -> 18    224     13.8 67   
140 -> 13    27      10.3 76   
141 -> 24    238     10.3 68   
142 -> 16    201     8    82   
143 -> 13    238     12.6 64   
144 -> 23    14      9.2  71   
145 -> 36    139     10.3 81   
146 -> 7     49      10.3 69   
147 -> 14    20      16.6 63   
148 -> 30    193     6.9  70   
150 -> 14    191     14.3 75   
151 -> 18    131     8    76   
152 -> 20    223     11.5 68   

    Coefficients =
     
Intercept -> -66.01138344691108  
Solar.R   -> 0.05943745007818751 
Wind      -> -3.2973494133331394 
Temp      -> 1.6688690596747198  

    FitIntercept = true
    yKey = "Ozone" }
val it: Series<string,float> =
  
Intercept -> -66.01138344691108  
Solar.R   -> 0.05943745007818751 
Wind      -> -3.2973494133331394 
Temp      -> 1.6688690596747198
// Fitted values (ŷ)
LinearRegression.Fit.fittedValues fit |> Series.take 6
val it: Series<int,float> =
  
1 -> 34.78201265222975   
2 -> 24.794504422670556  
3 -> 18.142901874063128  
6 -> 31.879698050658774  
7 -> -7.167223272359379  
8 -> -29.357782463263717
// Residuals (y − ŷ)
LinearRegression.Fit.residuals fit |> Series.take 6
val it: Series<int,float> =
  
1 -> 1.2179873477702472   
2 -> -12.794504422670556  
3 -> -0.14290187406312782 
6 -> -8.879698050658774   
7 -> 26.16722327235938    
8 -> 37.35778246326372

For a full summary including the t-table and R²:

let summary = LinearRegression.Fit.summary fit
printfn "%O" summary
// Formula: Ozone ~ Solar.R + Wind + Temp
//              Min:   1Q:   Median:   3Q   Max:
// ...
// R^2: 0.606, Adj. R^2: 0.596

To fit without an intercept pass false as the third argument to ols.


Tips and common patterns

Working with the full pipeline

A typical quantitative pipeline combines Deedle frame operations with Deedle.MathNetNumerics:

open Deedle
open Deedle.MathNetNumerics

// 1. Load data
let prices = Frame.ReadCsv("prices.csv") |> Frame.indexRowsDate "Date"

// 2. Compute daily log-returns
let logReturns = log prices - log (Frame.shift 1 prices) |> Frame.dropSparseRows

// 3. Rolling 60-day correlation matrix (one frame per row)
let rollingCorr = Finance.ewmCorr(logReturns, span=60.0)

// 4. Latest correlation frame
let latestCorr = rollingCorr |> Series.lastValue

Missing values

LinearRegression.ols will raise an error if any input column has missing values. Use Frame.dropSparseRows or Frame.fillMissingWith to clean data first:

let cleanDf = numAir |> Frame.dropSparseRows
let fit = LinearRegression.ols ["Solar.R";"Wind";"Temp"] "Ozone" true cleanDf

Similarly, Stats.corrMatrix / Stats.corr treat NaN as 0 in the covariance step (matching MATLAB semantics). Use Frame.dropSparseRows if you want listwise deletion.

Performance note

LinearAlgebra.transpose on a purely numeric frame is significantly faster than Frame.transpose because it bypasses the generic object boxing layer and works directly in float[] space.

namespace System
namespace Deedle
namespace Deedle.MathNetNumerics
namespace MathNet
namespace MathNet.Numerics
namespace MathNet.Numerics.LinearAlgebra
val fsi: FSharp.Compiler.Interactive.InteractiveSession
member FSharp.Compiler.Interactive.InteractiveSession.AddPrinter: ('T -> string) -> unit
val o: obj
type obj = Object
val iface: Type
Object.GetType() : Type
val fmt: Reflection.MethodInfo
Type.GetMethod(name: string) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, types: Type array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, types: Type array, modifiers: Reflection.ParameterModifier array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags, types: Type array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, genericParameterCount: int, types: Type array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, genericParameterCount: int, types: Type array, modifiers: Reflection.ParameterModifier array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, genericParameterCount: int, bindingAttr: Reflection.BindingFlags, types: Type array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags, binder: Reflection.Binder, types: Type array, modifiers: Reflection.ParameterModifier array) : Reflection.MethodInfo
   (+0 other overloads)
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags, binder: Reflection.Binder, callConvention: Reflection.CallingConventions, types: Type array, modifiers: Reflection.ParameterModifier array) : Reflection.MethodInfo
   (+0 other overloads)
Reflection.MethodBase.Invoke(obj: obj, parameters: obj array) : obj
Reflection.MethodBase.Invoke(obj: obj, invokeAttr: Reflection.BindingFlags, binder: Reflection.Binder, parameters: obj array, culture: Globalization.CultureInfo) : obj
Multiple items
val string: value: 'T -> string

--------------------
type string = String
val root: string
val df: Frame<int,string>
val frame: columns: ('a * #ISeries<'c>) seq -> Frame<'c,'a> (requires equality and equality)
<summary> A function for constructing data frame from a sequence of name - column pairs. This provides a nicer syntactic sugar for `Frame.ofColumns`. </summary>
<example> To create a simple frame with two columns, you can write: <code> frame [ "A" =&gt; series [ 1 =&gt; 30.0; 2 =&gt; 35.0 ] "B" =&gt; series [ 1 =&gt; 30.0; 3 =&gt; 40.0 ] ] </code></example>
<category>Frame construction</category>
val series: observations: ('a * 'b) seq -> Series<'a,'b> (requires equality)
<summary> Create a series from a sequence of key-value pairs that represent the observations of the series. This function can be used together with the `=&gt;` operator to create key-value pairs. </summary>
<example> // Creates a series with squares of numbers let sqs = series [ 1 =&gt; 1.0; 2 =&gt; 4.0; 3 =&gt; 9.0 ] </example>
val m: Matrix<float>
Multiple items
type Matrix = static member dot: df: Frame<'R,'C> * m2: Matrix<float> -> Frame<'R,'R> (requires equality and equality) + 11 overloads static member ofFrame: df: Frame<'a,'b> -> Matrix<float> (requires equality and equality) static member toFrame: rows: 'R seq -> cols: 'C seq -> m: Matrix<float> -> Frame<'R,'C> (requires equality and equality)
<summary> Matrix conversions and operators between Frame and Series &lt;category&gt;Matrix conversions and operators&lt;/category&gt; </summary>

--------------------
type Matrix<'T (requires default constructor and value type and 'T :> IEquatable<'T> and 'T :> IFormattable and 'T :> ValueType)> = interface IFormattable interface IEquatable<Matrix<'T>> interface ICloneable member Add: scalar: 'T -> Matrix<'T> + 3 overloads member Append: right: Matrix<'T> -> Matrix<'T> + 1 overload member AsArray: unit -> 'T array2d member AsColumnArrays: unit -> 'T array array member AsColumnMajorArray: unit -> 'T array member AsRowArrays: unit -> 'T array array member AsRowMajorArray: unit -> 'T array ...
<summary> Defines the base class for <c>Matrix</c> classes. </summary>
<summary> Defines the base class for <c>Matrix</c> classes. </summary>
<typeparam name="T">Supported data types are <c>double</c>, <c>single</c>, <see cref="N:MathNet.Numerics.LinearAlgebra.Complex" />, and <see cref="N:MathNet.Numerics.LinearAlgebra.Complex32" />.</typeparam>
<summary> Defines the base class for <c>Matrix</c> classes. </summary>
<summary> Defines the base class for <c>Matrix</c> classes. </summary>
Multiple items
val float: value: 'T -> float (requires member op_Explicit)

--------------------
type float = Double

--------------------
type float<'Measure> = float
Multiple items
module Frame from Deedle
<summary> The `Frame` module provides an F#-friendly API for working with data frames. The module follows the usual desing for collection-processing in F#, so the functions work well with the pipelining operator (`|&gt;`). For example, given a frame with two columns representing prices, we can use `Frame.pctChange` to calculate daily returns like this: let df = frame [ "MSFT" =&gt; prices1; "AAPL" =&gt; prices2 ] let rets = df |&gt; Frame.pctChange 1 rets |&gt; Stats.mean Note that the `Stats.mean` operation is overloaded and works both on series (returning a number) and on frames (returning a series). You can also use `Frame.diff` if you need absolute differences rather than relative changes. The functions in this module are designed to be used from F#. For a C#-friendly API, see the `FrameExtensions` type. For working with individual series, see the `Series` module. The functions in the `Frame` module are grouped in a number of categories and documented below. Accessing frame data and lookup ------------------------------- Functions in this category provide access to the values in the fame. You can also add and remove columns from a frame (which both return a new value). - `addCol`, `replaceCol` and `dropCol` can be used to create a new data frame with a new column, by replacing an existing column with a new one, or by dropping an existing column - `cols` and `rows` return the columns or rows of a frame as a series containing objects; `getCols` and `getRows` return a generic series and cast the values to the type inferred from the context (columns or rows of incompatible types are skipped); `getNumericCols` returns columns of a type convertible to `float` for convenience. - You can get a specific row or column using `get[Col|Row]` or `lookup[Col|Row]` functions. The `lookup` variant lets you specify lookup behavior for key matching (e.g. find the nearest smaller key than the specified value). There are also `[try]get` and `[try]Lookup` functions that return optional values and functions returning entire observations (key together with the series). - `sliceCols` and `sliceRows` return a sub-frame containing only the specified columns or rows. Finally, `toArray2D` returns the frame data as a 2D array. Grouping, windowing and chunking -------------------------------- The basic grouping functions in this category can be used to group the rows of a data frame by a specified projection or column to create a frame with hierarchical index such as <c>Frame&lt;'K1 * 'K2, 'C&gt;</c>. The functions always aggregate rows, so if you want to group columns, you need to use `Frame.transpose` first. The function `groupRowsBy` groups rows by the value of a specified column. Use `groupRowsBy[Int|Float|String...]` if you want to specify the type of the column in an easier way than using type inference; `groupRowsUsing` groups rows using the specified _projection function_ and `groupRowsByIndex` projects the grouping key just from the row index. More advanced functions include: `aggregateRowsBy` which groups the rows by a specified sequence of columns and aggregates each group into a single value; `pivotTable` implements the pivoting operation [as documented in the tutorials](../frame.html#pivot). The `melt` and `unmelt` functions turn the data frame into a single data frame containing columns `Row`, `Column` and `Value` containing the data of the original frame; `unmelt` can be used to turn this representation back into an original frame. The `stack` and `unstack` functions implement pandas-style reshape operations. `stack` converts `Frame&lt;'R,'C&gt;` to a long-format `Frame&lt;'R*'C, string&gt;` where each cell becomes a row keyed by `(rowKey, colKey)` with a single `"Value"` column. `unstack` promotes the inner row-key level to column keys, producing `Frame&lt;'R1, 'C*'R2&gt;` from `Frame&lt;'R1*'R2,'C&gt;`. A simple windowing functions that are exposed for an entire frame operations are `window` and `windowInto`. For more complex windowing operations, you currently have to use `mapRows` or `mapCols` and apply windowing on individual series. Sorting and index manipulation ------------------------------ A frame is indexed by row keys and column keys. Both of these indices can be sorted (by the keys). A frame that is sorted allows a number of additional operations (such as lookup using the `Lookp.ExactOrSmaller` lookup behavior). The functions in this category provide ways for manipulating the indices. It is expected that most operations are done on rows and so more functions are available in a row-wise way. A frame can alwyas be transposed using `Frame.transpose`. Index operations: The existing row/column keys can be replaced by a sequence of new keys using the `indexColsWith` and `indexRowsWith` functions. Row keys can also be replaced by ordinal numbers using `indexRowsOrdinally`. The function `indexRows` uses the specified column of the original frame as the index. It removes the column from the resulting frame (to avoid this, use overloaded `IndexRows` method). This function infers the type of row keys from the context, so it is usually more convenient to use `indexRows[Date|String|Int|...]` functions. Finally, if you want to calculate the index value based on multiple columns of the row, you can use `indexRowsUsing`. Sorting frame rows: Frame rows can be sorted according to the value of a specified column using the `sortRows` function; `sortRowsBy` takes a projection function which lets you transform the value of a column (e.g. to project a part of the value). The functions `sortRowsByKey` and `sortColsByKey` sort the rows or columns using the default ordering on the key values. The result is a frame with ordered index. Expanding columns: When the frame contains a series with complex .NET objects such as F# records or C# classes, it can be useful to "expand" the column. This operation looks at the type of the objects, gets all properties of the objects (recursively) and generates multiple series representing the properties as columns. The function `expandCols` expands the specified columns while `expandAllCols` applies the expansion to all columns of the data frame. Frame transformations --------------------- Functions in this category perform standard transformations on data frames including projections, filtering, taking some sub-frame of the frame, aggregating values using scanning and so on. Projection and filtering functions such as `[map|filter][Cols|Rows]` call the specified function with the column or row key and an <c>ObjectSeries&lt;'K&gt;</c> representing the column or row. You can use functions ending with `Values` (such as `mapRowValues`) when you do not require the row key, but only the row series; `mapRowKeys` and `mapColKeys` can be used to transform the keys. You can use `reduceValues` to apply a custom reduction to values of columns. Other aggregations are available in the `Stats` module. You can also get a row with the greaterst or smallest value of a given column using `[min|max]RowBy`. The functions `take[Last]` and `skip[Last]` can be used to take a sub-frame of the original source frame by skipping a specified number of rows. Note that this does not require an ordered frame and it ignores the index - for index-based lookup use slicing, such as `df.Rows.[lo .. hi]`, instead. Finally the `shift` function can be used to obtain a frame with values shifted by the specified offset. This can be used e.g. to get previous value for each key using `Frame.shift 1 df`. The `diff` function calculates difference from previous value using `df - (Frame.shift offs df)`. Processing frames with exceptions --------------------------------- The functions in this group can be used to write computations over frames that may fail. They use the type <c>tryval&lt;'T&gt;</c> which is defined as a discriminated union with two cases: Success containing a value, or Error containing an exception. Using <c>tryval&lt;'T&gt;</c> as a value in a data frame is not generally recommended, because the type of values cannot be tracked in the type. For this reason, it is better to use <c>tryval&lt;'T&gt;</c> with individual series. However, `tryValues` and `fillErrorsWith` functions can be used to get values, or fill failed values inside an entire data frame. The `tryMapRows` function is more useful. It can be used to write a transformation that applies a computation (which may fail) to each row of a data frame. The resulting series is of type <c>Series&lt;'R, tryval&lt;'T&gt;&gt;</c> and can be processed using the <c>Series</c> module functions. Missing values -------------- This group of functions provides a way of working with missing values in a data frame. The category provides the following functions that can be used to fill missing values: * `fillMissingWith` fills missing values with a specified constant * `fillMissingUsing` calls a specified function for every missing value * `fillMissing` and variants propagates values from previous/later keys We use the terms _sparse_ and _dense_ to denote series that contain some missing values or do not contain any missing values, respectively. The functions `denseCols` and `denseRows` return a series that contains only dense columns or rows and all sparse rows or columns are replaced with a missing value. The `dropSparseCols` and `dropSparseRows` functions drop these missing values and return a frame with no missing values. Joining, merging and zipping ---------------------------- The simplest way to join two frames is to use the `join` operation which can be used to perform left, right, outer or inner join of two frames. When the row keys of the frames do not match exactly, you can use `joinAlign` which takes an additional parameter that specifies how to find matching key in left/right join (e.g. by taking the nearest smaller available key). Frames that do not contian overlapping values can be combined using `merge` (when combining just two frames) or using `mergeAll` (for larger number of frames). Tha latter is optimized to work well for a large number of data frames. Finally, frames with overlapping values can be combined using `zip`. It takes a function that is used to combine the overlapping values. A `zipAlign` function provides a variant with more flexible row key matching (as in `joinAlign`) Hierarchical index operations ----------------------------- A data frame has a hierarchical row index if the row index is formed by a tuple, such as <c>Frame&lt;'R1 * 'R2, 'C&gt;</c>. Frames of this kind are returned, for example, by the grouping functions such as <c>Frame.groupRowsBy</c>. The functions in this category provide ways for working with data frames that have hierarchical row keys. The functions <c>applyLevel</c> and <c>reduceLevel</c> can be used to reduce values according to one of the levels. The <c>applyLevel</c> function takes a reduction of type <c>Series&lt;'K, 'T&gt; -&gt; 'T</c> while <c>reduceLevel</c> reduces individual values using a function of type <c>'T -&gt; 'T -&gt; 'T</c>. The functions <c>nest</c> and <c>unnest</c> can be used to convert between frames with hierarchical indices (<c>Frame&lt;'K1 * 'K2, 'C&gt;</c>) and series of frames that represent individual groups (<c>Series&lt;'K1, Frame&lt;'K2, 'C&gt;&gt;</c>). The <c>nestBy</c> function can be used to perform group by operation and return the result as a series of frems. </summary>
<category>Frame and series operations</category>


--------------------
type Frame = static member ofMatrix: rowKeys: 'R seq -> colKeys: 'C seq -> m: Matrix<'T> -> Frame<'R,'C> (requires equality and equality and default constructor and value type and 'T :> IEquatable<'T> and 'T :> IFormattable and 'T :> ValueType) static member toMatrix: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality)
<summary> Frame to matrix conversion &lt;category&gt;Matrix conversions and operators&lt;/category&gt; </summary>

--------------------
type Frame<'TRowKey,'TColumnKey (requires equality and equality)> = interface IDynamicMetaObjectProvider interface INotifyCollectionChanged interface IFrameFormattable interface IFsiFormattable interface IFrame new: rowIndex: IIndex<'TRowKey> * columnIndex: IIndex<'TColumnKey> * data: IVector<IVector> * indexBuilder: IIndexBuilder * vectorBuilder: IVectorBuilder -> Frame<'TRowKey,'TColumnKey> + 1 overload member AddColumn: column: 'TColumnKey * series: 'V seq -> unit + 3 overloads member AggregateRowsBy: groupBy: 'TColumnKey seq * aggBy: 'TColumnKey seq * aggFunc: Func<Series<'TRowKey,'a>,'b> -> Frame<int,'TColumnKey> member Clone: unit -> Frame<'TRowKey,'TColumnKey> member ColumnApply: f: Func<Series<'TRowKey,'T>,ISeries<'TRowKey>> -> Frame<'TRowKey,'TColumnKey> + 1 overload ...
<summary> A frame is the key Deedle data structure (together with series). It represents a data table (think spreadsheet or CSV file) with multiple rows and columns. The frame consists of row index, column index and data. The indices are used for efficient lookup when accessing data by the row key `'TRowKey` or by the column key `'TColumnKey`. Deedle frames are optimized for the scenario when all values in a given column are of the same type (but types of different columns can differ). </summary>
<remarks><para>Joining, zipping and appending:</para><para> More info </para></remarks>
<category>Core frame and series types</category>


--------------------
new: names: 'TColumnKey seq * columns: ISeries<'TRowKey> seq -> Frame<'TRowKey,'TColumnKey>
new: rowIndex: Indices.IIndex<'TRowKey> * columnIndex: Indices.IIndex<'TColumnKey> * data: IVector<IVector> * indexBuilder: Indices.IIndexBuilder * vectorBuilder: Vectors.IVectorBuilder -> Frame<'TRowKey,'TColumnKey>
static member Frame.toMatrix: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality)
static member Frame.ofMatrix: rowKeys: 'R seq -> colKeys: 'C seq -> m: Matrix<'T> -> Frame<'R,'C> (requires equality and equality and default constructor and value type and 'T :> IEquatable<'T> and 'T :> IFormattable and 'T :> ValueType)
val s: Series<string,float>
val v: Vector<float>
Multiple items
type Vector = static member ofOptionalValues: data: 'T option seq -> IVector<'T> + 2 overloads static member ofValues: data: 'T array -> IVector<'T> + 1 overload
<summary> Type that provides a simple access to creating vectors represented using the built-in `ArrayVector` type that stores the data in a continuous block of memory. </summary>

--------------------
type Vector<'T (requires default constructor and value type and 'T :> IEquatable<'T> and 'T :> IFormattable and 'T :> ValueType)> = interface IFormattable interface IEquatable<Vector<'T>> interface IList interface ICollection interface IEnumerable interface IList<'T> interface ICollection<'T> interface seq<'T> interface ICloneable override AbsoluteMaximum: unit -> 'T ...
<summary> Defines the generic class for <c>Vector</c> classes. </summary>
<typeparam name="T">Supported data types are double, single, <see cref="N:MathNet.Numerics.LinearAlgebra.Complex" />, and <see cref="N:MathNet.Numerics.LinearAlgebra.Complex32" />.</typeparam>
Multiple items
module Series from Deedle
<summary> The `Series` module provides an F#-friendly API for working with data and time series. The API follows the usual design for collection-processing in F#, so the functions work well with the pipelining (<c>|&gt;</c>) operator. For example, given a series with ages, we can use `Series.filterValues` to filter outliers and then `Stats.mean` to calculate the mean: ages |&gt; Series.filterValues (fun v -&gt; v &gt; 0.0 &amp;&amp; v &lt; 120.0) |&gt; Stats.mean The module provides comprehensive set of functions for working with series. The same API is also exposed using C#-friendly extension methods. In C#, the above snippet could be written as: [lang=csharp] ages .Where(kvp =&gt; kvp.Value &gt; 0.0 &amp;&amp; kvp.Value &lt; 120.0) .Mean() For more information about similar frame-manipulation functions, see the `Frame` module. For more information about C#-friendly extensions, see `SeriesExtensions`. The functions in the `Series` module are grouped in a number of categories and documented below. Accessing series data and lookup -------------------------------- Functions in this category provide access to the values in the series. - The term _observation_ is used for a key value pair in the series. - When working with a sorted series, it is possible to perform lookup using keys that are not present in the series - you can specify to search for the previous or next available value using _lookup behavior_. - Functions such as `get` and `getAll` have their counterparts `lookup` and `lookupAll` that let you specify lookup behavior. - For most of the functions that may fail, there is a `try[Foo]` variant that returns `None` instead of failing. - Functions with a name ending with `At` perform lookup based on the absolute integer offset (and ignore the keys of the series) Series transformations ---------------------- Functions in this category perform standard transformations on series including projections, filtering, taking some sub-series of the series, aggregating values using scanning and so on. Projection and filtering functions generally skip over missing values, but there are variants `filterAll` and `mapAll` that let you handle missing values explicitly. Keys can be transformed using `mapKeys`. When you do not need to consider the keys, and only care about values, use `filterValues` and `mapValues` (which is also aliased as the `$` operator). Series supports standard set of folding functions including `reduce` and `fold` (to reduce series values into a single value) as well as the `scan[All]` function, which can be used to fold values of a series into a series of intermeidate folding results. The functions `take[Last]` and `skip[Last]` can be used to take a sub-series of the original source series by skipping a specified number of elements. Note that this does not require an ordered series and it ignores the index - for index-based lookup use slicing, such as `series.[lo .. hi]`, instead. Finally the `shift` function can be used to obtain a series with values shifted by the specified offset. This can be used e.g. to get previous value for each key using `Series.shift 1 ts`. The `diff` function calculates difference from previous value using `ts - (Series.shift offs ts)`. Processing series with exceptions --------------------------------- The functions in this group can be used to write computations over series that may fail. They use the type <c>tryval&lt;'T&gt;</c> which is defined as a discriminated union with two cases: Success containing a value, or Error containing an exception. The function `tryMap` lets you create <c>Series&lt;'K, tryval&lt;'T&gt;&gt;</c> by mapping over values of an original series. You can then extract values using `tryValues`, which throws `AggregateException` if there were any errors. Functions `tryErrors` and `trySuccesses` give series containing only errors and successes. You can fill failed values with a constant using `fillErrorsWith`. Hierarchical index operations ----------------------------- When the key of a series is tuple, the elements of the tuple can be treated as multiple levels of a index. For example <c>Series&lt;'K1 * 'K2, 'V&gt;</c> has two levels with keys of types <c>'K1</c> and <c>'K2</c> respectively. The functions in this cateogry provide a way for aggregating values in the series at one of the levels. For example, given a series `input` indexed by two-element tuple, you can calculate mean for different first-level values as follows: input |&gt; applyLevel fst Stats.mean Note that the `Stats` module provides helpers for typical statistical operations, so the above could be written just as `input |&gt; Stats.levelMean fst`. Grouping, windowing and chunking -------------------------------- This category includes functions that group data from a series in some way. Two key concepts here are _window_ and _chunk_. Window refers to (overlapping) sliding windows over the input series while chunk refers to non-overlapping blocks of the series. The boundary behavior can be specified using the `Boundary` flags. The value `Skip` means that boundaries (incomplete windows or chunks) should be skipped. The value `AtBeginning` and `AtEnding` can be used to define at which side should the boundary be returned (or skipped). For chunking, `AtBeginning ||| Skip` makes sense and it means that the incomplete chunk at the beginning should be skipped (aligning the last chunk with the end). The behavior may be specified in a number of ways (which is reflected in the name): - `dist` - using an absolute distance between the keys - `while` - using a condition on the first and last key - `size` - by specifying the absolute size of the window/chunk The functions ending with `Into` take a function to be applied to the window/chunk. The functions `window`, `windowInto` and `chunk`, `chunkInto` are simplified versions that take a size. There is also `pairwise` function for sliding window of size two. Missing values -------------- This group of functions provides a way of working with missing values in a series. The `dropMissing` function drops all keys for which there are no values in the series. The `withMissingFrom` function lets you copy missing values from another series. The remaining functions provide different mechanism for filling the missing values. * `fillMissingWith` fills missing values with a specified constant * `fillMissingUsing` calls a specified function for every missing value * `fillMissing` and variants propagates values from previous/later keys Sorting and index manipulation ------------------------------ A series that is sorted by keys allows a number of additional operations (such as lookup using the `Lookp.ExactOrSmaller` lookup behavior). However, it is also possible to sort series based on the values - although the functions for manipulation with series do not guarantee that the order will be preserved. To sort series by keys, use `sortByKey`. Other sorting functions let you sort the series using a specified comparer function (`sortWith`), using a projection function (`sortBy`) and using the default comparison (`sort`). In addition, you can also replace the keys of a series with other keys using `indexWith` or with integers using `indexOrdinally`. To pick and reorder series values using to match a list of keys use `realign`. Sampling, resampling and advanced lookup ---------------------------------------- Given a (typically) time series sampling or resampling makes it possible to get time series with representative values at lower or uniform frequency. We use the following terminology: - `lookup` and `sample` functions find values at specified key; if a key is not available, they can look for value associated with the nearest smaller or the nearest greater key. - `resample` function aggregate values values into chunks based on a specified collection of keys (e.g. explicitly provided times), or based on some relation between keys (e.g. date times having the same date). - `resampleUniform` is similar to resampling, but we specify keys by providing functions that generate a uniform sequence of keys (e.g. days), the operation also fills value for days that have no corresponding observations in the input sequence. Joining, merging and zipping ---------------------------- Given two series, there are two ways to combine the values. If the keys in the series are not overlapping (or you want to throw away values from one or the other series), then you can use `merge` or `mergeUsing`. To merge more than 2 series efficiently, use the `mergeAll` function, which has been optimized for large number of series. If you want to align two series, you can use the _zipping_ operation. This aligns two series based on their keys and gives you tuples of values. The default behavior (`zip`) uses outer join and exact matching. For ordered series, you can specify other forms of key lookups (e.g. find the greatest smaller key) using `zipAlign`. functions ending with `Into` are generally easier to use as they call a specified function to turn the tuple (of possibly missing values) into a new value. For more complicated behaviors, it is often convenient to use joins on frames instead of working with series. Create two frames with single columns and then use the join operation. The result will be a frame with two columns (which is easier to use than series of tuples). </summary>
<category>Frame and series operations</category>


--------------------
type Series = static member ofVector: keys: 'K seq -> v: Vector<float> -> Series<'K,float> (requires equality) static member toVector: s: Series<'K,float> -> Vector<float> (requires equality)

--------------------
type Series<'K,'V (requires equality)> = interface ISeriesFormattable interface IFsiFormattable interface ISeries<'K> new: index: IIndex<'K> * vector: IVector<'V> * vectorBuilder: IVectorBuilder * indexBuilder: IIndexBuilder -> Series<'K,'V> + 3 overloads member After: lowerExclusive: 'K -> Series<'K,'V> member Aggregate: aggregation: Aggregation<'K> * keySelector: Func<DataSegment<Series<'K,'V>>,'TNewKey> * valueSelector: Func<DataSegment<Series<'K,'V>>,OptionalValue<'R>> -> Series<'TNewKey,'R> (requires equality) + 1 overload member AsyncMaterialize: unit -> Async<Series<'K,'V>> member Before: upperExclusive: 'K -> Series<'K,'V> member Between: lowerInclusive: 'K * upperInclusive: 'K -> Series<'K,'V> member Compare: another: Series<'K,'V> -> Series<'K,Diff<'V>> ...
<summary> The type <c>Series&lt;K, V&gt;</c> represents a data series consisting of values `V` indexed by keys `K`. The keys of a series may or may not be ordered </summary>
<category>Core frame and series types</category>


--------------------
new: pairs: Collections.Generic.KeyValuePair<'K,'V> seq -> Series<'K,'V>
new: keys: 'K seq * values: 'V seq -> Series<'K,'V>
new: keys: 'K array * values: 'V array -> Series<'K,'V>
new: index: Indices.IIndex<'K> * vector: IVector<'V> * vectorBuilder: Vectors.IVectorBuilder * indexBuilder: Indices.IIndexBuilder -> Series<'K,'V>
static member Series.toVector: s: Series<'K,float> -> Vector<float> (requires equality)
static member Series.ofVector: keys: 'K seq -> v: Vector<float> -> Series<'K,float> (requires equality)
type Matrix = static member dot: df: Frame<'R,'C> * m2: Matrix<float> -> Frame<'R,'R> (requires equality and equality) + 11 overloads static member ofFrame: df: Frame<'a,'b> -> Matrix<float> (requires equality and equality) static member toFrame: rows: 'R seq -> cols: 'C seq -> m: Matrix<float> -> Frame<'R,'C> (requires equality and equality)
<summary> Matrix conversions and operators between Frame and Series &lt;category&gt;Matrix conversions and operators&lt;/category&gt; </summary>
static member Matrix.dot: s1: Series<'C,float> * s2: Series<'C,float> -> float (requires equality)
   (+0 other overloads)
static member Matrix.dot: s: Series<'C,float> * df: Frame<'R,'C> -> Series<'C,float> (requires comparison and equality)
   (+0 other overloads)
static member Matrix.dot: df: Frame<'R,'C> * s: Series<'C,float> -> Series<'C,float> (requires equality and comparison)
   (+0 other overloads)
static member Matrix.dot: df1: Frame<'R0,'C> * df2: Frame<'C,'R1> -> Frame<'R0,'R1> (requires equality and comparison and equality)
   (+0 other overloads)
static member Matrix.dot: s: Series<'R,float> * v: MathNet.Numerics.LinearAlgebra.Vector<float> -> float (requires equality)
   (+0 other overloads)
static member Matrix.dot: v: MathNet.Numerics.LinearAlgebra.Vector<float> * s: Series<'R,float> -> float (requires equality)
   (+0 other overloads)
static member Matrix.dot: m: MathNet.Numerics.LinearAlgebra.Matrix<float> * s: Series<'K,float> -> MathNet.Numerics.LinearAlgebra.Vector<float> (requires equality)
   (+0 other overloads)
static member Matrix.dot: s: Series<'K,float> * m: MathNet.Numerics.LinearAlgebra.Matrix<float> -> MathNet.Numerics.LinearAlgebra.Vector<float> (requires equality)
   (+0 other overloads)
static member Matrix.dot: df: Frame<'R,'C> * v: MathNet.Numerics.LinearAlgebra.Vector<float> -> Series<'R,float> (requires equality and equality)
   (+0 other overloads)
static member Matrix.dot: v: MathNet.Numerics.LinearAlgebra.Vector<float> * df: Frame<'R,'C> -> MathNet.Numerics.LinearAlgebra.Vector<float> (requires equality and equality)
   (+0 other overloads)
type LinearAlgebra = static member cholesky: df: Frame<'R,'C> -> Cholesky<float> (requires equality and equality) static member condition: df: Frame<'R,'C> -> float (requires equality and equality) static member conjugate: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality) static member conjugateTranspose: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality) static member determinant: df: Frame<'R,'C> -> float (requires equality and equality) static member eigen: df: Frame<'R,'C> -> Evd<float> (requires equality and equality) static member inverse: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality) static member isHermitian: df: Frame<'R,'C> -> bool (requires equality and equality) static member isSymmetric: df: Frame<'R,'C> -> bool (requires equality and equality) static member kernel: df: Frame<'R,'C> -> Vector<float> array (requires equality and equality) ...
<summary> Linear algebra on frame using MathNet.Numerics library. &lt;category&gt;Linear Algebra&lt;/category&gt; </summary>
static member LinearAlgebra.transpose: df: Frame<'R,'C> -> Frame<'C,'R> (requires equality and equality)
val sq: Frame<int,string>
static member LinearAlgebra.inverse: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality)
val air: Frame<int,string>
static member Frame.ReadCsv: reader: IO.TextReader * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) -> Frame<int,string>
static member Frame.ReadCsv: stream: IO.Stream * hasHeaders: Nullable<bool> * inferTypes: Nullable<bool> * inferRows: Nullable<int> * schema: string * separators: string * culture: string * maxRows: Nullable<int> * missingValues: string array * preferOptions: Nullable<bool> * encoding: Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: location: string * hasHeaders: Nullable<bool> * inferTypes: Nullable<bool> * inferRows: Nullable<int> * schema: string * separators: string * culture: string * maxRows: Nullable<int> * missingValues: string array * preferOptions: bool * encoding: Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: path: string * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) * ?encoding: Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: stream: IO.Stream * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) * ?encoding: Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: path: string * indexCol: string * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) * ?encoding: Text.Encoding -> Frame<'R,string> (requires equality)
val ozone: Series<int,float>
val dropMissing: series: Series<'K,'T> -> Series<'K,'T> (requires equality)
<summary> Drop missing values from the specified series. The returned series contains only those keys for which there is a value available in the original one. </summary>
<param name="series">An input series to be filtered</param>
<example><code> let s = series [ 1 =&gt; 1.0; 2 =&gt; Double.NaN ] s |&gt; Series.dropMissing // val it : Series&lt;int,float&gt; = series [ 1 =&gt; 1] </code></example>
<category>Missing values</category>
type Stats = static member corr: df: Frame<'R,'C> * ?method: CorrelationMethod -> Frame<'C,'C> (requires equality and equality) + 1 overload static member corr2Cov: sigmaSeries: Series<'C,float> * corrFrame: Frame<'C,'C> -> Frame<'C,'C> (requires equality) static member corrMatrix: df: Frame<'R,'C> * ?method: CorrelationMethod -> Matrix<float> (requires equality and equality) static member cov: df: Frame<'R,'C> -> Frame<'C,'C> (requires equality and equality) static member cov2Corr: covFrame: Frame<'C,'C> -> Series<'C,float> * Frame<'C,'C> (requires equality) static member covMatrix: df: Frame<'R,'C> -> Matrix<float> (requires equality and equality) static member ewmMean: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality) + 1 overload static member median: series: Series<'R,'V> -> float (requires equality and member op_Explicit) + 1 overload static member movingCovarianceParallel: window: int -> df: Frame<'R,'C> -> Series<'R,Matrix<float>> (requires equality and equality) static member movingStdDevParallel: window: int -> df: Frame<'R,'C> -> Frame<'R,'C> (requires equality and equality) ...
<summary> Statistical analysis using MathNet.Numerics &lt;category&gt;Statistical Analysis&lt;/category&gt; </summary>
Multiple items
static member Stats.median: df: Frame<'R,'C> -> Series<'C,float> (requires equality and equality)
static member Stats.median: series: Series<'R,'V> -> float (requires equality and member op_Explicit)

--------------------
static member Stats.median: frame: Frame<'R,'C> -> Series<'C,float> (requires equality and equality)
static member Stats.median: series: Series<'K,'V> -> float (requires equality)
Multiple items
static member Stats.quantile: df: Frame<'R,'C> * tau: float * ?definition: MathNet.Numerics.Statistics.QuantileDefinition -> Series<'C,float> (requires equality and equality)
static member Stats.quantile: series: Series<'R,'V> * tau: float * ?definition: MathNet.Numerics.Statistics.QuantileDefinition -> float (requires equality and member op_Explicit)

--------------------
static member Stats.quantile: quantiles: float array * series: Series<'K,'V> -> Series<string,float> (requires equality)
static member Stats.ranks: df: Frame<'R,'C> * ?rankDefinition: MathNet.Numerics.Statistics.RankDefinition -> Frame<'R,'C> (requires equality and equality)
static member Stats.ranks: series: Series<'R,'V> * ?rankDefinition: MathNet.Numerics.Statistics.RankDefinition -> Series<'R,float> (requires equality and member op_Explicit)
val take: count: int -> series: Series<'K,'T> -> Series<'K,'T> (requires equality)
<summary> Returns a series that contains the specified number of keys from the original series. </summary>
<param name="count">Number of keys to take; must be smaller or equal to the original number of keys</param>
<param name="series">Input series from which the keys are taken</param>
<category>Series transformations</category>
val numAir: Frame<int,string>
val sliceCols: columns: 'C seq -> frame: Frame<'R,'C> -> Frame<'R,'C> (requires equality and equality)
<summary> Returns a frame consisting of the specified columns from the original data frame. The function uses exact key matching semantics. &lt;category&gt;Accessing frame data and lookup&lt;/category&gt; </summary>
val dropSparseRows: frame: Frame<'R,'C> -> Frame<'R,'C> (requires equality and equality)
<summary> Creates a new data frame that contains only those rows of the original data frame that are _dense_, meaning that they have a value for each column. The resulting data frame has the same number of columns, but may have fewer rows (or no rows at all). </summary>
<category>Missing values</category>
Multiple items
static member Stats.corr: df: Frame<'R,'C> * ?method: CorrelationMethod -> Frame<'C,'C> (requires equality and equality)
static member Stats.corr: s1: Series<'K,float> * s2: Series<'K,float> * ?method: CorrelationMethod -> 'a (requires equality)

--------------------
static member Stats.corr: series1: Series<'K,'V1> -> series2: Series<'K,'V2> -> float (requires equality)
type CorrelationMethod = | Pearson = 0 | Spearman = 1
<summary> Correlation method (Pearson or Spearman) &lt;category&gt;Statistical Analysis&lt;/category&gt; </summary>
CorrelationMethod.Spearman: CorrelationMethod = 1
<summary> Spearman correlation </summary>
Multiple items
static member Stats.cov: df: Frame<'R,'C> -> Frame<'C,'C> (requires equality and equality)

--------------------
static member Stats.cov: series1: Series<'K,'V1> -> series2: Series<'K,'V2> -> float (requires equality)
val stdDevs: Series<'a,float> (requires equality)
val corrFrame: Frame<'a,'a> (requires equality)
static member Stats.cov2Corr: covFrame: Frame<'C,'C> -> Series<'C,float> * Frame<'C,'C> (requires equality)
val recoveredCov: Frame<'a,'a> (requires equality)
static member Stats.corr2Cov: sigmaSeries: Series<'C,float> * corrFrame: Frame<'C,'C> -> Frame<'C,'C> (requires equality)
val returns: Series<int,float>
val i: int
type Math = static member Abs: value: decimal -> decimal + 7 overloads static member Acos: d: float -> float static member Acosh: d: float -> float static member Asin: d: float -> float static member Asinh: d: float -> float static member Atan: d: float -> float static member Atan2: y: float * x: float -> float static member Atanh: d: float -> float static member BigMul: a: int * b: int -> int64 + 5 overloads static member BitDecrement: x: float -> float ...
<summary>Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions.</summary>
Math.Sin(a: float) : float
static member Stats.ewmMean: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Frame<'R,'C> (requires equality and equality)
static member Stats.ewmMean: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality)
val rollingStd: Frame<'a,'b> (requires equality and equality)
static member Stats.movingStdDevParallel: window: int -> df: Frame<'R,'C> -> Frame<'R,'C> (requires equality and equality)
val rollingCov: Series<'a,MathNet.Numerics.LinearAlgebra.Matrix<float>> (requires equality)
static member Stats.movingCovarianceParallel: window: int -> df: Frame<'R,'C> -> Series<'R,MathNet.Numerics.LinearAlgebra.Matrix<float>> (requires equality and equality)
val prices: Series<int,float>
Math.Exp(d: float) : float
val dailyReturns: Series<int,float>
static member SeriesExtensions.Diff: series: Series<'K,float> * offset: int -> Series<'K,float> (requires equality)
static member SeriesExtensions.Shift: series: Series<'K,'V> * offset: int -> Series<'K,'V> (requires equality)
type Finance = static member ewmCorr: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,Frame<'C,'C>> (requires equality and equality) static member ewmCorrMatrix: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,Matrix<float>> (requires equality and equality) static member ewmCov: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,Frame<'C,'C>> (requires equality and equality) static member ewmCovMatrix: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,Matrix<float>> (requires equality and equality) static member ewmCrossCov: x: Series<'R,float> * y: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality) static member ewmCrossVol: x: Series<'R,float> * y: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality) static member ewmVar: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality) + 1 overload static member ewmVolRMS: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality) + 1 overload static member ewmVolStdDev: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality) + 1 overload
<summary> Financial analysis &lt;category&gt;Financial Analysis&lt;/category&gt; </summary>
static member Finance.ewmVolStdDev: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Frame<'R,'C> (requires equality and equality)
static member Finance.ewmVolStdDev: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality)
static member Finance.ewmVolRMS: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Frame<'R,'C> (requires equality and equality)
static member Finance.ewmVolRMS: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality)
static member Finance.ewmVar: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Frame<'R,'C> (requires equality and equality)
static member Finance.ewmVar: x: Series<'R,float> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,float> (requires equality)
val ewmCovFrames: Series<'a,Frame<'b,'b>> (requires equality and equality)
static member Finance.ewmCov: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,Frame<'C,'C>> (requires equality and equality)
val ewmCorrFrames: Series<'a,Frame<'b,'b>> (requires equality and equality)
static member Finance.ewmCorr: df: Frame<'R,'C> * ?com: float * ?span: float * ?halfLife: float * ?alpha: float -> Series<'R,Frame<'C,'C>> (requires equality and equality)
val normed: Frame<int,string>
module PCA from Deedle.MathNetNumerics
val normalizeColumns: df: Frame<'a,'b> -> Frame<'a,'b> (requires equality and equality)
<summary> Normalizes the columns in the dataframe using a z-score. That is (X - mean) / (std. dev) </summary>
<param name="df">The dataframe to normalize</param>
val result: PCA.t<string>
val pca: dataFrame: Frame<'a,'b> -> PCA.t<'b> (requires equality and equality)
<summary> Computes the principal components from the data frame. The principal components are listed from PC1 .. PCn Where PC1 explains most of the variance. </summary>
<param name="dataFrame">A PCA datatype that contains the eigen values and vectors.</param>
PCA.t.EigenValues: Series<string,float>
PCA.t.EigenVectors: Frame<string,string>
val ev: Series<string,float>
val eigenValues: pca: PCA.t<'a> -> Series<string,float> (requires equality)
<summary> The eigen values of the PCA transformation. </summary>
<param name="pca">The PCA transformation.</param>
val vecs: Frame<'a,string> (requires equality)
val eigenVectors: pca: PCA.t<'a> -> Frame<'a,string> (requires equality)
<summary> The eigen vectors of the PCA transformation. </summary>
<param name="pca">The PCA transformation.</param>
val fit: LinearRegression.Fit.t<'a> (requires equality)
module LinearRegression from Deedle.MathNetNumerics
val ols: xCols: string seq -> yCol: string -> fitIntercept: bool -> df: Frame<'a,string> -> LinearRegression.Fit.t<'a> (requires equality)
<summary> Performs linear regression on the values in a dataframe. </summary>
<param name="xCols">The column keys that constitutes the independent variables.</param>
<param name="yCol">The column key that consitutes the dependent variable.</param>
<param name="fitIntercept">An option type that specifies a key to use for the intercept in the result, if set to None, the fit will not produce an intercept.</param>
<param name="df">The dataframe to perform the regression on</param>
<returns>A series with column keys as keys, and regression coefficients as values.</returns>
val fit: LinearRegression.Fit.t<int>
module Fit from Deedle.MathNetNumerics.LinearRegression
val coefficients: fit: LinearRegression.Fit.t<'a> -> Series<string,float> (requires equality)
<summary> The coefficients found by the linear regression. </summary>
<param name="fit">The fit.</param>
val fittedValues: fit: LinearRegression.Fit.t<'a> -> Series<'a,float> (requires equality)
<summary> Computes the fitted values from the linear model. </summary>
<param name="fit">The fit.</param>
val residuals: fit: LinearRegression.Fit.t<'a> -> Series<'a,float> (requires equality)
<summary> Computes the residuals of the regression (y - yHat) </summary>
<param name="fit">The fit.</param>
val summary: LinearRegression.Fit.Summary.t
val summary: fit: LinearRegression.Fit.t<'a> -> LinearRegression.Fit.Summary.t (requires equality)
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
val prices: Frame<System.DateTime,string>
static member Frame.ReadCsv: reader: System.IO.TextReader * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) -> Frame<int,string>
static member Frame.ReadCsv: stream: System.IO.Stream * hasHeaders: System.Nullable<bool> * inferTypes: System.Nullable<bool> * inferRows: System.Nullable<int> * schema: string * separators: string * culture: string * maxRows: System.Nullable<int> * missingValues: string array * preferOptions: System.Nullable<bool> * encoding: System.Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: location: string * hasHeaders: System.Nullable<bool> * inferTypes: System.Nullable<bool> * inferRows: System.Nullable<int> * schema: string * separators: string * culture: string * maxRows: System.Nullable<int> * missingValues: string array * preferOptions: bool * encoding: System.Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: path: string * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) * ?encoding: System.Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: stream: System.IO.Stream * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) * ?encoding: System.Text.Encoding -> Frame<int,string>
static member Frame.ReadCsv: path: string * indexCol: string * ?hasHeaders: bool * ?inferTypes: bool * ?inferRows: int * ?schema: string * ?separators: string * ?culture: string * ?maxRows: int * ?missingValues: string array * ?preferOptions: bool * ?typeResolver: (string -> string option) * ?encoding: System.Text.Encoding -> Frame<'R,string> (requires equality)
val logReturns: Frame<System.DateTime,string>
val log: value: 'T -> 'T (requires member Log)
val shift: offset: int -> frame: Frame<'R,'C> -> Frame<'R,'C> (requires equality and equality)
<summary> Returns a frame with columns shifted by the specified offset. When the offset is positive, the values are shifted forward and first `offset` keys are dropped. When the offset is negative, the values are shifted backwards and the last `offset` keys are dropped. Expressed in pseudo-code: result[k] = series[k - offset] </summary>
<param name="offset">Can be both positive and negative number.</param>
<param name="frame">The input frame whose columns are to be shifted.</param>
<remarks> If you want to calculate the difference, e.g. `df - (Frame.shift 1 df)`, you can use `Frame.diff` which will be a little bit faster. </remarks>
<category>Frame transformations</category>
val rollingCorr: Series<System.DateTime,Frame<string,string>>
val latestCorr: Frame<string,string>
Multiple items
module Series from Deedle
<summary> The `Series` module provides an F#-friendly API for working with data and time series. The API follows the usual design for collection-processing in F#, so the functions work well with the pipelining (<c>|&gt;</c>) operator. For example, given a series with ages, we can use `Series.filterValues` to filter outliers and then `Stats.mean` to calculate the mean: ages |&gt; Series.filterValues (fun v -&gt; v &gt; 0.0 &amp;&amp; v &lt; 120.0) |&gt; Stats.mean The module provides comprehensive set of functions for working with series. The same API is also exposed using C#-friendly extension methods. In C#, the above snippet could be written as: [lang=csharp] ages .Where(kvp =&gt; kvp.Value &gt; 0.0 &amp;&amp; kvp.Value &lt; 120.0) .Mean() For more information about similar frame-manipulation functions, see the `Frame` module. For more information about C#-friendly extensions, see `SeriesExtensions`. The functions in the `Series` module are grouped in a number of categories and documented below. Accessing series data and lookup -------------------------------- Functions in this category provide access to the values in the series. - The term _observation_ is used for a key value pair in the series. - When working with a sorted series, it is possible to perform lookup using keys that are not present in the series - you can specify to search for the previous or next available value using _lookup behavior_. - Functions such as `get` and `getAll` have their counterparts `lookup` and `lookupAll` that let you specify lookup behavior. - For most of the functions that may fail, there is a `try[Foo]` variant that returns `None` instead of failing. - Functions with a name ending with `At` perform lookup based on the absolute integer offset (and ignore the keys of the series) Series transformations ---------------------- Functions in this category perform standard transformations on series including projections, filtering, taking some sub-series of the series, aggregating values using scanning and so on. Projection and filtering functions generally skip over missing values, but there are variants `filterAll` and `mapAll` that let you handle missing values explicitly. Keys can be transformed using `mapKeys`. When you do not need to consider the keys, and only care about values, use `filterValues` and `mapValues` (which is also aliased as the `$` operator). Series supports standard set of folding functions including `reduce` and `fold` (to reduce series values into a single value) as well as the `scan[All]` function, which can be used to fold values of a series into a series of intermeidate folding results. The functions `take[Last]` and `skip[Last]` can be used to take a sub-series of the original source series by skipping a specified number of elements. Note that this does not require an ordered series and it ignores the index - for index-based lookup use slicing, such as `series.[lo .. hi]`, instead. Finally the `shift` function can be used to obtain a series with values shifted by the specified offset. This can be used e.g. to get previous value for each key using `Series.shift 1 ts`. The `diff` function calculates difference from previous value using `ts - (Series.shift offs ts)`. Processing series with exceptions --------------------------------- The functions in this group can be used to write computations over series that may fail. They use the type <c>tryval&lt;'T&gt;</c> which is defined as a discriminated union with two cases: Success containing a value, or Error containing an exception. The function `tryMap` lets you create <c>Series&lt;'K, tryval&lt;'T&gt;&gt;</c> by mapping over values of an original series. You can then extract values using `tryValues`, which throws `AggregateException` if there were any errors. Functions `tryErrors` and `trySuccesses` give series containing only errors and successes. You can fill failed values with a constant using `fillErrorsWith`. Hierarchical index operations ----------------------------- When the key of a series is tuple, the elements of the tuple can be treated as multiple levels of a index. For example <c>Series&lt;'K1 * 'K2, 'V&gt;</c> has two levels with keys of types <c>'K1</c> and <c>'K2</c> respectively. The functions in this cateogry provide a way for aggregating values in the series at one of the levels. For example, given a series `input` indexed by two-element tuple, you can calculate mean for different first-level values as follows: input |&gt; applyLevel fst Stats.mean Note that the `Stats` module provides helpers for typical statistical operations, so the above could be written just as `input |&gt; Stats.levelMean fst`. Grouping, windowing and chunking -------------------------------- This category includes functions that group data from a series in some way. Two key concepts here are _window_ and _chunk_. Window refers to (overlapping) sliding windows over the input series while chunk refers to non-overlapping blocks of the series. The boundary behavior can be specified using the `Boundary` flags. The value `Skip` means that boundaries (incomplete windows or chunks) should be skipped. The value `AtBeginning` and `AtEnding` can be used to define at which side should the boundary be returned (or skipped). For chunking, `AtBeginning ||| Skip` makes sense and it means that the incomplete chunk at the beginning should be skipped (aligning the last chunk with the end). The behavior may be specified in a number of ways (which is reflected in the name): - `dist` - using an absolute distance between the keys - `while` - using a condition on the first and last key - `size` - by specifying the absolute size of the window/chunk The functions ending with `Into` take a function to be applied to the window/chunk. The functions `window`, `windowInto` and `chunk`, `chunkInto` are simplified versions that take a size. There is also `pairwise` function for sliding window of size two. Missing values -------------- This group of functions provides a way of working with missing values in a series. The `dropMissing` function drops all keys for which there are no values in the series. The `withMissingFrom` function lets you copy missing values from another series. The remaining functions provide different mechanism for filling the missing values. * `fillMissingWith` fills missing values with a specified constant * `fillMissingUsing` calls a specified function for every missing value * `fillMissing` and variants propagates values from previous/later keys Sorting and index manipulation ------------------------------ A series that is sorted by keys allows a number of additional operations (such as lookup using the `Lookp.ExactOrSmaller` lookup behavior). However, it is also possible to sort series based on the values - although the functions for manipulation with series do not guarantee that the order will be preserved. To sort series by keys, use `sortByKey`. Other sorting functions let you sort the series using a specified comparer function (`sortWith`), using a projection function (`sortBy`) and using the default comparison (`sort`). In addition, you can also replace the keys of a series with other keys using `indexWith` or with integers using `indexOrdinally`. To pick and reorder series values using to match a list of keys use `realign`. Sampling, resampling and advanced lookup ---------------------------------------- Given a (typically) time series sampling or resampling makes it possible to get time series with representative values at lower or uniform frequency. We use the following terminology: - `lookup` and `sample` functions find values at specified key; if a key is not available, they can look for value associated with the nearest smaller or the nearest greater key. - `resample` function aggregate values values into chunks based on a specified collection of keys (e.g. explicitly provided times), or based on some relation between keys (e.g. date times having the same date). - `resampleUniform` is similar to resampling, but we specify keys by providing functions that generate a uniform sequence of keys (e.g. days), the operation also fills value for days that have no corresponding observations in the input sequence. Joining, merging and zipping ---------------------------- Given two series, there are two ways to combine the values. If the keys in the series are not overlapping (or you want to throw away values from one or the other series), then you can use `merge` or `mergeUsing`. To merge more than 2 series efficiently, use the `mergeAll` function, which has been optimized for large number of series. If you want to align two series, you can use the _zipping_ operation. This aligns two series based on their keys and gives you tuples of values. The default behavior (`zip`) uses outer join and exact matching. For ordered series, you can specify other forms of key lookups (e.g. find the greatest smaller key) using `zipAlign`. functions ending with `Into` are generally easier to use as they call a specified function to turn the tuple (of possibly missing values) into a new value. For more complicated behaviors, it is often convenient to use joins on frames instead of working with series. Create two frames with single columns and then use the join operation. The result will be a frame with two columns (which is easier to use than series of tuples). </summary>
<category>Frame and series operations</category>


--------------------
type Series = static member ofVector: keys: 'K seq -> v: Vector<float> -> Series<'K,float> (requires equality) static member toVector: s: Series<'K,float> -> Vector<float> (requires equality)

--------------------
type Series<'K,'V (requires equality)> = interface ISeriesFormattable interface IFsiFormattable interface ISeries<'K> new: index: IIndex<'K> * vector: IVector<'V> * vectorBuilder: IVectorBuilder * indexBuilder: IIndexBuilder -> Series<'K,'V> + 3 overloads member After: lowerExclusive: 'K -> Series<'K,'V> member Aggregate: aggregation: Aggregation<'K> * keySelector: Func<DataSegment<Series<'K,'V>>,'TNewKey> * valueSelector: Func<DataSegment<Series<'K,'V>>,OptionalValue<'R>> -> Series<'TNewKey,'R> (requires equality) + 1 overload member AsyncMaterialize: unit -> Async<Series<'K,'V>> member Before: upperExclusive: 'K -> Series<'K,'V> member Between: lowerInclusive: 'K * upperInclusive: 'K -> Series<'K,'V> member Compare: another: Series<'K,'V> -> Series<'K,Diff<'V>> ...
<summary> The type <c>Series&lt;K, V&gt;</c> represents a data series consisting of values `V` indexed by keys `K`. The keys of a series may or may not be ordered </summary>
<category>Core frame and series types</category>


--------------------
new: pairs: System.Collections.Generic.KeyValuePair<'K,'V> seq -> Series<'K,'V>
new: keys: 'K seq * values: 'V seq -> Series<'K,'V>
new: keys: 'K array * values: 'V array -> Series<'K,'V>
new: index: Indices.IIndex<'K> * vector: IVector<'V> * vectorBuilder: Vectors.IVectorBuilder * indexBuilder: Indices.IIndexBuilder -> Series<'K,'V>
val lastValue: series: Series<'K,'V> -> 'V (requires equality)
<summary> Returns the last value of the series. This fails if the last value is missing. </summary>
<category>Accessing series data and lookup</category>
val cleanDf: Frame<'a,string> (requires equality)

Type something to start searching.