Indexes and Labels in C# QuickStart Sample
Illustrates how to use indexes to label the rows and columns of a data frame or matrix, or the elements of a vector in C#.
View this sample in: Visual Basic F#
using System;
using Numerics.NET.DataAnalysis;
using Numerics.NET;
using Index = Numerics.NET.DataAnalysis.Index;
namespace IndexesAndLabels {
/// <summary>
/// Illustrates how to use indexes to label the elements
/// of a vector, or the rows and columns of a matrix.
/// </summary>
class IndexesAndLabels {
static void Main(string[] args) {
// The license is verified at runtime. We're using
// a 30 day trial key here. For more information, see
// https://numerics.net/trial-key
Numerics.NET.License.Verify("64542-18980-57619-62268");
//
// Indexes
//
// An index is a set of keys that can be used
// to label one or more dimensions of a vector,
// matrix, or data frame.
//
// Construction
//
// The simplest way to create an index is from an array:
var index = Index.Create(new[] { "a", "b", "c", "d" });
// We can then assign this to the Index property of a vector:
var v = Vector.Create(new double[] { 1.0, 2.0, 3.0, 4.0 });
v.Index = index;
Console.WriteLine(v);
// An index by position is very common,
// and can be created efficiently using the
// Default method:
var numbers = Index.Default(10); // 0, 1, ..., 9
var numbers2 = Index.Default(10, 20); // 10, 11, ..., 19
// Various options exist to create indexes over date ranges,
// for example:
var dateIndex = Index.CreateDateRange(new DateTime(2015, 4, 25), 10);
// 2015/4/25, 2015/4/26, ..., 2015/5/4
// Finally, for some purposes it may be useful to create
// an index of intervals, for example when you want to
// categorize people into age groups:
int[] ages = { 0, 18, 35, 65 };
var ageGroups = Index.CreateBins(ages, SpecialBins.AboveMaximum);
//
// Properties
//
// Indexes have a length
Console.WriteLine($"# of keys in index: {index.Length}");
// Indexes usually have unique elements.
Console.WriteLine($"Keys are unique? {index.IsUnique}");
// The elements may be sorted or not.
Console.WriteLine($"Keys are sorted? {index.IsSorted}");
Console.WriteLine($"Sort order: {index.SortOrder}");
//
// Lookup
//
// Once created, you can look up the position of a key:
var position = index.Lookup("c"); // = 2
if (index.TryLookup("e", out position))
Console.WriteLine("We shouldn't be here.");
// You can also look up the nearest date.
var dates = Index.CreateDateRange(DateTime.Today.AddDays(-5), 10);
var now = DateTime.Now;
// An exact lookup fails in this case:
if (!dates.TryLookup(now, out position))
Console.WriteLine("Exact lookup failed.");
// But looking for the nearest key works fine:
position = dates.LookupNearest(now, Direction.Backward); // = 5
position = dates.LookupNearest(now, Direction.Forward); // = 6
//
// Automatic alignment
//
// One of the useful features of indexes is that
// values are aligned on key values automatically.
// For example, given two vectors:
var a = Vector.Create(
new[] { 1.0, 2.0, 3.0, 4.0 },
new[] { "a", "b", "c", "d" });
var b = Vector.Create(
new[] { 10.0, 30.0, 40.0, 50.0 },
new[] { "a", "c", "d", "e" });
// We can compute their sum:
Console.WriteLine(a + b);
// and we find that elements are added
// when they have the same key,
// not when they have the same position.
// Indexes also propagate through calculations:
Console.WriteLine($"Exp(a) = \n{Vector.Exp(a)}");
Console.WriteLine($"a[a % 2 == 0] =\n{a[x => x % 2 == 0]}");
// Matrices can have a row and/or a column index:
var c = Matrix.CreateRandom(100, 4);
c.ColumnIndex = Index.Create(new[] { "a", "b", "c", "d" });
var cTc = c.Transpose() * c;
Console.WriteLine($"C^T*C = \n{cTc.Summarize()}");
Console.Write("Press any key to exit.");
Console.ReadLine();
}
}
}