diff --git a/src/Microsoft.Data.Analysis/BooleanDataFrameColumn.cs b/src/Microsoft.Data.Analysis/BooleanDataFrameColumn.cs new file mode 100644 index 0000000000..982463d182 --- /dev/null +++ b/src/Microsoft.Data.Analysis/BooleanDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class BooleanDataFrameColumn : PrimitiveDataFrameColumn + { + public BooleanDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public BooleanDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public BooleanDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public BooleanDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal BooleanDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/ByteDataFrameColumn.cs b/src/Microsoft.Data.Analysis/ByteDataFrameColumn.cs new file mode 100644 index 0000000000..369e6d33ee --- /dev/null +++ b/src/Microsoft.Data.Analysis/ByteDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class ByteDataFrameColumn : PrimitiveDataFrameColumn + { + public ByteDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public ByteDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public ByteDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public ByteDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal ByteDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/CharDataFrameColumn.cs b/src/Microsoft.Data.Analysis/CharDataFrameColumn.cs new file mode 100644 index 0000000000..1dcedc4fc9 --- /dev/null +++ b/src/Microsoft.Data.Analysis/CharDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class CharDataFrameColumn : PrimitiveDataFrameColumn + { + public CharDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public CharDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public CharDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public CharDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal CharDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/ColumnArithmeticTemplate.ttinclude b/src/Microsoft.Data.Analysis/ColumnArithmeticTemplate.ttinclude index 55960ee376..f97eea5a1e 100644 --- a/src/Microsoft.Data.Analysis/ColumnArithmeticTemplate.ttinclude +++ b/src/Microsoft.Data.Analysis/ColumnArithmeticTemplate.ttinclude @@ -38,6 +38,56 @@ return $"{keyword} (typeof(T) == typeof({type.TypeName}))"; } + // A way to discern implicit conversions. For ex: short has primitivitty 2. int has primitivitty 3. primitivitty(short) + primitivitty(int) > 2 * primitivitty(short) implying that a conversion has to take place + public Dictionary primitiveTypeToPrimitivityLevelMap = new Dictionary { + {"byte", 1}, + {"sbyte", 1}, + {"short", 2}, + {"ushort", 2}, + {"int", 3}, + {"uint", 3}, + {"long", 4}, + {"ulong", 4}, + {"float", 5}, + {"double", 6}, + {"decimal", 7} + }; + + public string GetCapitalizedPrimitiveTypes(string type) + { + string typeFirstCharUpper; + if (type.First() == 'u' || type == "sbyte") + { + typeFirstCharUpper = type[0].ToString().ToUpper() + type[1].ToString().ToUpper() + type.Substring(2); + } + else + { + typeFirstCharUpper = type[0].ToString().ToUpper() + type.Substring(1); + } + return typeFirstCharUpper; + } + + public bool IsMixedSignedAndUnsignedTypePair(string t1, string t2) + { + if (t1 == "byte" && t2 == "sbyte") + { + return true; + } + if (t2 == "byte" && t1 == "sbyte") + { + return true; + } + if (("u" + t1) == t2) + { + return true; + } + if (("u" + t2) == t1) + { + return true; + } + return false; + } + public TypeConfiguration[] typeConfiguration = new [] { new TypeConfiguration("bool", oneLiteral:"true", zeroLiteral:"false", supportsNumeric: false, unsupportedMethods: new[] {"LeftShift", "RightShift"}), @@ -55,6 +105,30 @@ new TypeConfiguration("ushort", classPrefix:"UShort", unsupportedMethods: new[] {"UnaryMinus", "All", "Any"}) }; + public string GetBinaryOperationReturnType(TypeConfiguration t1, TypeConfiguration t2) + { + int t1Level; + if (!primitiveTypeToPrimitivityLevelMap.TryGetValue(t1.TypeName, out t1Level)) + { + throw new Exception("Unknown type"); + } + int t2Level; + if (!primitiveTypeToPrimitivityLevelMap.TryGetValue(t2.TypeName, out t2Level)) + { + throw new Exception("Unknown type"); + } + if (t1Level + t2Level <= 2 * t1Level) + { + return t1.TypeName; + } + if (t1Level + t2Level <= 2 * t2Level) + { + return t2.TypeName; + } + throw new Exception("Bug in GetBinaryOperationReturnType"); + return ""; + } + public enum MethodType { Unary, diff --git a/src/Microsoft.Data.Analysis/Converters.cs b/src/Microsoft.Data.Analysis/Converters.cs new file mode 100644 index 0000000000..a3d2abc67c --- /dev/null +++ b/src/Microsoft.Data.Analysis/Converters.cs @@ -0,0 +1,948 @@ + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Generated from Converters.tt. Do not modify directly + +using System; +using System.Collections.Generic; + +namespace Microsoft.Data.Analysis +{ + internal interface IByteConverter + { + byte GetByte(T value); + } + internal static class ByteConverter + { + public static IByteConverter Instance { get; } = ByteConverter.GetByteConverter(); + } + internal static class ByteConverter + { + public static IByteConverter GetByteConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IByteConverter)new ByteByteConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IByteConverter)new SByteByteConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteByteConverter : IByteConverter + { + public byte GetByte(byte value) + { + return (byte)value; + } + } + internal class SByteByteConverter : IByteConverter + { + public byte GetByte(sbyte value) + { + return (byte)value; + } + } + internal interface ISByteConverter + { + sbyte GetSByte(T value); + } + internal static class SByteConverter + { + public static ISByteConverter Instance { get; } = SByteConverter.GetSByteConverter(); + } + internal static class SByteConverter + { + public static ISByteConverter GetSByteConverter() + { + if (typeof(T) == typeof(byte)) + { + return (ISByteConverter)new ByteSByteConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (ISByteConverter)new SByteSByteConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteSByteConverter : ISByteConverter + { + public sbyte GetSByte(byte value) + { + return (sbyte)value; + } + } + internal class SByteSByteConverter : ISByteConverter + { + public sbyte GetSByte(sbyte value) + { + return (sbyte)value; + } + } + internal interface IShortConverter + { + short GetShort(T value); + } + internal static class ShortConverter + { + public static IShortConverter Instance { get; } = ShortConverter.GetShortConverter(); + } + internal static class ShortConverter + { + public static IShortConverter GetShortConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IShortConverter)new ByteShortConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IShortConverter)new SByteShortConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IShortConverter)new ShortShortConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IShortConverter)new UShortShortConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteShortConverter : IShortConverter + { + public short GetShort(byte value) + { + return (short)value; + } + } + internal class SByteShortConverter : IShortConverter + { + public short GetShort(sbyte value) + { + return (short)value; + } + } + internal class ShortShortConverter : IShortConverter + { + public short GetShort(short value) + { + return (short)value; + } + } + internal class UShortShortConverter : IShortConverter + { + public short GetShort(ushort value) + { + return (short)value; + } + } + internal interface IUShortConverter + { + ushort GetUShort(T value); + } + internal static class UShortConverter + { + public static IUShortConverter Instance { get; } = UShortConverter.GetUShortConverter(); + } + internal static class UShortConverter + { + public static IUShortConverter GetUShortConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IUShortConverter)new ByteUShortConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IUShortConverter)new SByteUShortConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IUShortConverter)new ShortUShortConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IUShortConverter)new UShortUShortConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteUShortConverter : IUShortConverter + { + public ushort GetUShort(byte value) + { + return (ushort)value; + } + } + internal class SByteUShortConverter : IUShortConverter + { + public ushort GetUShort(sbyte value) + { + return (ushort)value; + } + } + internal class ShortUShortConverter : IUShortConverter + { + public ushort GetUShort(short value) + { + return (ushort)value; + } + } + internal class UShortUShortConverter : IUShortConverter + { + public ushort GetUShort(ushort value) + { + return (ushort)value; + } + } + internal interface IIntConverter + { + int GetInt(T value); + } + internal static class IntConverter + { + public static IIntConverter Instance { get; } = IntConverter.GetIntConverter(); + } + internal static class IntConverter + { + public static IIntConverter GetIntConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IIntConverter)new ByteIntConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IIntConverter)new SByteIntConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IIntConverter)new ShortIntConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IIntConverter)new UShortIntConverter(); + } + if (typeof(T) == typeof(int)) + { + return (IIntConverter)new IntIntConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (IIntConverter)new UIntIntConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteIntConverter : IIntConverter + { + public int GetInt(byte value) + { + return (int)value; + } + } + internal class SByteIntConverter : IIntConverter + { + public int GetInt(sbyte value) + { + return (int)value; + } + } + internal class ShortIntConverter : IIntConverter + { + public int GetInt(short value) + { + return (int)value; + } + } + internal class UShortIntConverter : IIntConverter + { + public int GetInt(ushort value) + { + return (int)value; + } + } + internal class IntIntConverter : IIntConverter + { + public int GetInt(int value) + { + return (int)value; + } + } + internal class UIntIntConverter : IIntConverter + { + public int GetInt(uint value) + { + return (int)value; + } + } + internal interface IUIntConverter + { + uint GetUInt(T value); + } + internal static class UIntConverter + { + public static IUIntConverter Instance { get; } = UIntConverter.GetUIntConverter(); + } + internal static class UIntConverter + { + public static IUIntConverter GetUIntConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IUIntConverter)new ByteUIntConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IUIntConverter)new SByteUIntConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IUIntConverter)new ShortUIntConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IUIntConverter)new UShortUIntConverter(); + } + if (typeof(T) == typeof(int)) + { + return (IUIntConverter)new IntUIntConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (IUIntConverter)new UIntUIntConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteUIntConverter : IUIntConverter + { + public uint GetUInt(byte value) + { + return (uint)value; + } + } + internal class SByteUIntConverter : IUIntConverter + { + public uint GetUInt(sbyte value) + { + return (uint)value; + } + } + internal class ShortUIntConverter : IUIntConverter + { + public uint GetUInt(short value) + { + return (uint)value; + } + } + internal class UShortUIntConverter : IUIntConverter + { + public uint GetUInt(ushort value) + { + return (uint)value; + } + } + internal class IntUIntConverter : IUIntConverter + { + public uint GetUInt(int value) + { + return (uint)value; + } + } + internal class UIntUIntConverter : IUIntConverter + { + public uint GetUInt(uint value) + { + return (uint)value; + } + } + internal interface ILongConverter + { + long GetLong(T value); + } + internal static class LongConverter + { + public static ILongConverter Instance { get; } = LongConverter.GetLongConverter(); + } + internal static class LongConverter + { + public static ILongConverter GetLongConverter() + { + if (typeof(T) == typeof(byte)) + { + return (ILongConverter)new ByteLongConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (ILongConverter)new SByteLongConverter(); + } + if (typeof(T) == typeof(short)) + { + return (ILongConverter)new ShortLongConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (ILongConverter)new UShortLongConverter(); + } + if (typeof(T) == typeof(int)) + { + return (ILongConverter)new IntLongConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (ILongConverter)new UIntLongConverter(); + } + if (typeof(T) == typeof(long)) + { + return (ILongConverter)new LongLongConverter(); + } + if (typeof(T) == typeof(ulong)) + { + return (ILongConverter)new ULongLongConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteLongConverter : ILongConverter + { + public long GetLong(byte value) + { + return (long)value; + } + } + internal class SByteLongConverter : ILongConverter + { + public long GetLong(sbyte value) + { + return (long)value; + } + } + internal class ShortLongConverter : ILongConverter + { + public long GetLong(short value) + { + return (long)value; + } + } + internal class UShortLongConverter : ILongConverter + { + public long GetLong(ushort value) + { + return (long)value; + } + } + internal class IntLongConverter : ILongConverter + { + public long GetLong(int value) + { + return (long)value; + } + } + internal class UIntLongConverter : ILongConverter + { + public long GetLong(uint value) + { + return (long)value; + } + } + internal class LongLongConverter : ILongConverter + { + public long GetLong(long value) + { + return (long)value; + } + } + internal class ULongLongConverter : ILongConverter + { + public long GetLong(ulong value) + { + return (long)value; + } + } + internal interface IULongConverter + { + ulong GetULong(T value); + } + internal static class ULongConverter + { + public static IULongConverter Instance { get; } = ULongConverter.GetULongConverter(); + } + internal static class ULongConverter + { + public static IULongConverter GetULongConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IULongConverter)new ByteULongConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IULongConverter)new SByteULongConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IULongConverter)new ShortULongConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IULongConverter)new UShortULongConverter(); + } + if (typeof(T) == typeof(int)) + { + return (IULongConverter)new IntULongConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (IULongConverter)new UIntULongConverter(); + } + if (typeof(T) == typeof(long)) + { + return (IULongConverter)new LongULongConverter(); + } + if (typeof(T) == typeof(ulong)) + { + return (IULongConverter)new ULongULongConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteULongConverter : IULongConverter + { + public ulong GetULong(byte value) + { + return (ulong)value; + } + } + internal class SByteULongConverter : IULongConverter + { + public ulong GetULong(sbyte value) + { + return (ulong)value; + } + } + internal class ShortULongConverter : IULongConverter + { + public ulong GetULong(short value) + { + return (ulong)value; + } + } + internal class UShortULongConverter : IULongConverter + { + public ulong GetULong(ushort value) + { + return (ulong)value; + } + } + internal class IntULongConverter : IULongConverter + { + public ulong GetULong(int value) + { + return (ulong)value; + } + } + internal class UIntULongConverter : IULongConverter + { + public ulong GetULong(uint value) + { + return (ulong)value; + } + } + internal class LongULongConverter : IULongConverter + { + public ulong GetULong(long value) + { + return (ulong)value; + } + } + internal class ULongULongConverter : IULongConverter + { + public ulong GetULong(ulong value) + { + return (ulong)value; + } + } + internal interface IFloatConverter + { + float GetFloat(T value); + } + internal static class FloatConverter + { + public static IFloatConverter Instance { get; } = FloatConverter.GetFloatConverter(); + } + internal static class FloatConverter + { + public static IFloatConverter GetFloatConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IFloatConverter)new ByteFloatConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IFloatConverter)new SByteFloatConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IFloatConverter)new ShortFloatConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IFloatConverter)new UShortFloatConverter(); + } + if (typeof(T) == typeof(int)) + { + return (IFloatConverter)new IntFloatConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (IFloatConverter)new UIntFloatConverter(); + } + if (typeof(T) == typeof(long)) + { + return (IFloatConverter)new LongFloatConverter(); + } + if (typeof(T) == typeof(ulong)) + { + return (IFloatConverter)new ULongFloatConverter(); + } + if (typeof(T) == typeof(float)) + { + return (IFloatConverter)new FloatFloatConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteFloatConverter : IFloatConverter + { + public float GetFloat(byte value) + { + return (float)value; + } + } + internal class SByteFloatConverter : IFloatConverter + { + public float GetFloat(sbyte value) + { + return (float)value; + } + } + internal class ShortFloatConverter : IFloatConverter + { + public float GetFloat(short value) + { + return (float)value; + } + } + internal class UShortFloatConverter : IFloatConverter + { + public float GetFloat(ushort value) + { + return (float)value; + } + } + internal class IntFloatConverter : IFloatConverter + { + public float GetFloat(int value) + { + return (float)value; + } + } + internal class UIntFloatConverter : IFloatConverter + { + public float GetFloat(uint value) + { + return (float)value; + } + } + internal class LongFloatConverter : IFloatConverter + { + public float GetFloat(long value) + { + return (float)value; + } + } + internal class ULongFloatConverter : IFloatConverter + { + public float GetFloat(ulong value) + { + return (float)value; + } + } + internal class FloatFloatConverter : IFloatConverter + { + public float GetFloat(float value) + { + return (float)value; + } + } + internal interface IDoubleConverter + { + double GetDouble(T value); + } + internal static class DoubleConverter + { + public static IDoubleConverter Instance { get; } = DoubleConverter.GetDoubleConverter(); + } + internal static class DoubleConverter + { + public static IDoubleConverter GetDoubleConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IDoubleConverter)new ByteDoubleConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IDoubleConverter)new SByteDoubleConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IDoubleConverter)new ShortDoubleConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IDoubleConverter)new UShortDoubleConverter(); + } + if (typeof(T) == typeof(int)) + { + return (IDoubleConverter)new IntDoubleConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (IDoubleConverter)new UIntDoubleConverter(); + } + if (typeof(T) == typeof(long)) + { + return (IDoubleConverter)new LongDoubleConverter(); + } + if (typeof(T) == typeof(ulong)) + { + return (IDoubleConverter)new ULongDoubleConverter(); + } + if (typeof(T) == typeof(float)) + { + return (IDoubleConverter)new FloatDoubleConverter(); + } + if (typeof(T) == typeof(double)) + { + return (IDoubleConverter)new DoubleDoubleConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteDoubleConverter : IDoubleConverter + { + public double GetDouble(byte value) + { + return (double)value; + } + } + internal class SByteDoubleConverter : IDoubleConverter + { + public double GetDouble(sbyte value) + { + return (double)value; + } + } + internal class ShortDoubleConverter : IDoubleConverter + { + public double GetDouble(short value) + { + return (double)value; + } + } + internal class UShortDoubleConverter : IDoubleConverter + { + public double GetDouble(ushort value) + { + return (double)value; + } + } + internal class IntDoubleConverter : IDoubleConverter + { + public double GetDouble(int value) + { + return (double)value; + } + } + internal class UIntDoubleConverter : IDoubleConverter + { + public double GetDouble(uint value) + { + return (double)value; + } + } + internal class LongDoubleConverter : IDoubleConverter + { + public double GetDouble(long value) + { + return (double)value; + } + } + internal class ULongDoubleConverter : IDoubleConverter + { + public double GetDouble(ulong value) + { + return (double)value; + } + } + internal class FloatDoubleConverter : IDoubleConverter + { + public double GetDouble(float value) + { + return (double)value; + } + } + internal class DoubleDoubleConverter : IDoubleConverter + { + public double GetDouble(double value) + { + return (double)value; + } + } + internal interface IDecimalConverter + { + decimal GetDecimal(T value); + } + internal static class DecimalConverter + { + public static IDecimalConverter Instance { get; } = DecimalConverter.GetDecimalConverter(); + } + internal static class DecimalConverter + { + public static IDecimalConverter GetDecimalConverter() + { + if (typeof(T) == typeof(byte)) + { + return (IDecimalConverter)new ByteDecimalConverter(); + } + if (typeof(T) == typeof(sbyte)) + { + return (IDecimalConverter)new SByteDecimalConverter(); + } + if (typeof(T) == typeof(short)) + { + return (IDecimalConverter)new ShortDecimalConverter(); + } + if (typeof(T) == typeof(ushort)) + { + return (IDecimalConverter)new UShortDecimalConverter(); + } + if (typeof(T) == typeof(int)) + { + return (IDecimalConverter)new IntDecimalConverter(); + } + if (typeof(T) == typeof(uint)) + { + return (IDecimalConverter)new UIntDecimalConverter(); + } + if (typeof(T) == typeof(long)) + { + return (IDecimalConverter)new LongDecimalConverter(); + } + if (typeof(T) == typeof(ulong)) + { + return (IDecimalConverter)new ULongDecimalConverter(); + } + if (typeof(T) == typeof(float)) + { + return (IDecimalConverter)new FloatDecimalConverter(); + } + if (typeof(T) == typeof(double)) + { + return (IDecimalConverter)new DoubleDecimalConverter(); + } + if (typeof(T) == typeof(decimal)) + { + return (IDecimalConverter)new DecimalDecimalConverter(); + } + throw new NotSupportedException(); + } + } + internal class ByteDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(byte value) + { + return (decimal)value; + } + } + internal class SByteDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(sbyte value) + { + return (decimal)value; + } + } + internal class ShortDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(short value) + { + return (decimal)value; + } + } + internal class UShortDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(ushort value) + { + return (decimal)value; + } + } + internal class IntDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(int value) + { + return (decimal)value; + } + } + internal class UIntDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(uint value) + { + return (decimal)value; + } + } + internal class LongDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(long value) + { + return (decimal)value; + } + } + internal class ULongDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(ulong value) + { + return (decimal)value; + } + } + internal class FloatDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(float value) + { + return (decimal)value; + } + } + internal class DoubleDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(double value) + { + return (decimal)value; + } + } + internal class DecimalDecimalConverter : IDecimalConverter + { + public decimal GetDecimal(decimal value) + { + return (decimal)value; + } + } +} diff --git a/src/Microsoft.Data.Analysis/Converters.tt b/src/Microsoft.Data.Analysis/Converters.tt new file mode 100644 index 0000000000..c21661f75e --- /dev/null +++ b/src/Microsoft.Data.Analysis/Converters.tt @@ -0,0 +1,84 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<#@ include file="ColumnArithmeticTemplate.ttinclude" #> +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Generated from Converters.tt. Do not modify directly + +using System; +using System.Collections.Generic; + +namespace Microsoft.Data.Analysis +{ +<# + foreach (var typeToLevel in primitiveTypeToPrimitivityLevelMap) + { + string type = typeToLevel.Key; + int level = typeToLevel.Value; + string typeFirstCharUpper = GetCapitalizedPrimitiveTypes(type); +#> + internal interface I<#=typeFirstCharUpper#>Converter + { + <#=type#> Get<#=typeFirstCharUpper#>(T value); + } + internal static class <#=typeFirstCharUpper#>Converter + { + public static I<#=typeFirstCharUpper#>Converter Instance { get; } = <#=typeFirstCharUpper#>Converter.Get<#=typeFirstCharUpper#>Converter(); + } + internal static class <#=typeFirstCharUpper#>Converter + { + public static I<#=typeFirstCharUpper#>Converter Get<#=typeFirstCharUpper#>Converter() + { +<# + foreach (var typeLoop in primitiveTypeToPrimitivityLevelMap) + { + int loopLevel = typeLoop.Value; + if (loopLevel > level) + { + continue; + } +#> + if (typeof(T) == typeof(<#=typeLoop.Key#>)) + { +<# + string capitalizedLoopPrimitive = GetCapitalizedPrimitiveTypes(typeLoop.Key); +#> + return (I<#=typeFirstCharUpper#>Converter)new <#=capitalizedLoopPrimitive#><#=typeFirstCharUpper#>Converter(); + } +<# + } +#> + throw new NotSupportedException(); + } + } +<# + // Generate the individual type converter classes + foreach (var typeLoop in primitiveTypeToPrimitivityLevelMap) + { + int loopLevel = typeLoop.Value; + if (loopLevel > level) + { + continue; + } + string capitalizedLoopPrimitive = GetCapitalizedPrimitiveTypes(typeLoop.Key); +#> + internal class <#=capitalizedLoopPrimitive#><#=typeFirstCharUpper#>Converter : I<#=typeFirstCharUpper#>Converter<<#=typeLoop.Key#>> + { + public <#=type#> Get<#=typeFirstCharUpper#>(<#=typeLoop.Key#> value) + { + return (<#=type#>)value; + } + } +<# + } +#> +<# + } +#> +} diff --git a/src/Microsoft.Data.Analysis/DecimalConverter.cs b/src/Microsoft.Data.Analysis/DecimalConverter.cs deleted file mode 100644 index 97240969b0..0000000000 --- a/src/Microsoft.Data.Analysis/DecimalConverter.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Data.Analysis -{ - internal interface IDecimalConverter - { - decimal GetDecimal(T value); - } - internal static class DecimalConverter - { - public static IDecimalConverter Instance { get; } = DecimalConverter.GetDecimalConverter(); - } - internal static class DecimalConverter - { - public static IDecimalConverter GetDecimalConverter() - { - if (typeof(T) == typeof(bool)) - { - throw new NotImplementedException(); - } - else if (typeof(T) == typeof(byte)) - { - return (IDecimalConverter)new ByteDecimalConverter(); - } - else if (typeof(T) == typeof(char)) - { - return (IDecimalConverter)new CharDecimalConverter(); - } - else if (typeof(T) == typeof(decimal)) - { - return (IDecimalConverter)new DecimalDecimalConverter(); - } - else if (typeof(T) == typeof(double)) - { - return (IDecimalConverter)new DoubleDecimalConverter(); - } - else if (typeof(T) == typeof(float)) - { - return (IDecimalConverter)new FloatDecimalConverter(); - } - else if (typeof(T) == typeof(int)) - { - return (IDecimalConverter)new IntDecimalConverter(); - } - else if (typeof(T) == typeof(long)) - { - return (IDecimalConverter)new LongDecimalConverter(); - } - else if (typeof(T) == typeof(sbyte)) - { - return (IDecimalConverter)new SByteDecimalConverter(); - } - else if (typeof(T) == typeof(short)) - { - return (IDecimalConverter)new ShortDecimalConverter(); - } - else if (typeof(T) == typeof(uint)) - { - return (IDecimalConverter)new UIntDecimalConverter(); - } - else if (typeof(T) == typeof(ulong)) - { - return (IDecimalConverter)new ULongDecimalConverter(); - } - else if (typeof(T) == typeof(ushort)) - { - return (IDecimalConverter)new UShortDecimalConverter(); - } - throw new NotSupportedException(); - } - } - - internal class ByteDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(byte value) - { - return value; - } - } - - internal class CharDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(char value) - { - return value; - } - } - - internal class DecimalDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(decimal value) - { - return value; - } - } - - internal class DoubleDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(double value) - { - return (decimal)value; - } - } - - internal class FloatDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(float value) - { - return (decimal)value; - } - } - - internal class IntDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(int value) - { - return value; - } - } - - internal class LongDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(long value) - { - return value; - } - } - - internal class SByteDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(sbyte value) - { - return value; - } - } - - internal class ShortDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(short value) - { - return value; - } - } - - internal class UIntDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(uint value) - { - return value; - } - } - - internal class ULongDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(ulong value) - { - return value; - } - } - - internal class UShortDecimalConverter : IDecimalConverter - { - public decimal GetDecimal(ushort value) - { - return value; - } - } -} diff --git a/src/Microsoft.Data.Analysis/DecimalDataFrameColumn.cs b/src/Microsoft.Data.Analysis/DecimalDataFrameColumn.cs new file mode 100644 index 0000000000..b0b4fafd04 --- /dev/null +++ b/src/Microsoft.Data.Analysis/DecimalDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class DecimalDataFrameColumn : PrimitiveDataFrameColumn + { + public DecimalDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public DecimalDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public DecimalDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public DecimalDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal DecimalDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/DoubleConverter.cs b/src/Microsoft.Data.Analysis/DoubleConverter.cs deleted file mode 100644 index 399c3ffb25..0000000000 --- a/src/Microsoft.Data.Analysis/DoubleConverter.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Data.Analysis -{ - internal interface IDoubleConverter - { - double GetDouble(T value); - } - internal static class DoubleConverter - { - public static IDoubleConverter Instance { get; } = DoubleConverter.GetDoubleConverter(); - } - internal static class DoubleConverter - { - public static IDoubleConverter GetDoubleConverter() - { - if (typeof(T) == typeof(bool)) - { - throw new NotImplementedException(); - } - else if (typeof(T) == typeof(byte)) - { - return (IDoubleConverter)new ByteDoubleConverter(); - } - else if (typeof(T) == typeof(char)) - { - return (IDoubleConverter)new CharDoubleConverter(); - } - else if (typeof(T) == typeof(decimal)) - { - throw new NotImplementedException(); - } - else if (typeof(T) == typeof(double)) - { - return (IDoubleConverter)new DoubleDoubleConverter(); - } - else if (typeof(T) == typeof(float)) - { - return (IDoubleConverter)new FloatDoubleConverter(); - } - else if (typeof(T) == typeof(int)) - { - return (IDoubleConverter)new IntDoubleConverter(); - } - else if (typeof(T) == typeof(long)) - { - return (IDoubleConverter)new LongDoubleConverter(); - } - else if (typeof(T) == typeof(sbyte)) - { - return (IDoubleConverter)new SByteDoubleConverter(); - } - else if (typeof(T) == typeof(short)) - { - return (IDoubleConverter)new ShortDoubleConverter(); - } - else if (typeof(T) == typeof(uint)) - { - return (IDoubleConverter)new UIntDoubleConverter(); - } - else if (typeof(T) == typeof(ulong)) - { - return (IDoubleConverter)new ULongDoubleConverter(); - } - else if (typeof(T) == typeof(ushort)) - { - return (IDoubleConverter)new UShortDoubleConverter(); - } - throw new NotSupportedException(); - } - } - - internal class ByteDoubleConverter : IDoubleConverter - { - public double GetDouble(byte value) - { - return value; - } - } - - internal class CharDoubleConverter : IDoubleConverter - { - public double GetDouble(char value) - { - return value; - } - } - - internal class DoubleDoubleConverter : IDoubleConverter - { - public double GetDouble(double value) - { - return value; - } - } - - internal class FloatDoubleConverter : IDoubleConverter - { - public double GetDouble(float value) - { - return value; - } - } - - internal class IntDoubleConverter : IDoubleConverter - { - public double GetDouble(int value) - { - return value; - } - } - - internal class LongDoubleConverter : IDoubleConverter - { - public double GetDouble(long value) - { - return value; - } - } - - internal class SByteDoubleConverter : IDoubleConverter - { - public double GetDouble(sbyte value) - { - return value; - } - } - - internal class ShortDoubleConverter : IDoubleConverter - { - public double GetDouble(short value) - { - return value; - } - } - - internal class UIntDoubleConverter : IDoubleConverter - { - public double GetDouble(uint value) - { - return value; - } - } - - internal class ULongDoubleConverter : IDoubleConverter - { - public double GetDouble(ulong value) - { - return value; - } - } - - internal class UShortDoubleConverter : IDoubleConverter - { - public double GetDouble(ushort value) - { - return value; - } - } -} diff --git a/src/Microsoft.Data.Analysis/DoubleDataFrameColumn.cs b/src/Microsoft.Data.Analysis/DoubleDataFrameColumn.cs new file mode 100644 index 0000000000..6a97300376 --- /dev/null +++ b/src/Microsoft.Data.Analysis/DoubleDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class DoubleDataFrameColumn : PrimitiveDataFrameColumn + { + public DoubleDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public DoubleDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public DoubleDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public DoubleDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal DoubleDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/Int16DataFrameColumn.cs b/src/Microsoft.Data.Analysis/Int16DataFrameColumn.cs new file mode 100644 index 0000000000..79893b1899 --- /dev/null +++ b/src/Microsoft.Data.Analysis/Int16DataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class Int16DataFrameColumn : PrimitiveDataFrameColumn + { + public Int16DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public Int16DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public Int16DataFrameColumn(string name, long length = 0) : base(name, length) { } + + public Int16DataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal Int16DataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/Int32DataFrameColumn.cs b/src/Microsoft.Data.Analysis/Int32DataFrameColumn.cs new file mode 100644 index 0000000000..91b15764cd --- /dev/null +++ b/src/Microsoft.Data.Analysis/Int32DataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class Int32DataFrameColumn : PrimitiveDataFrameColumn + { + public Int32DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public Int32DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public Int32DataFrameColumn(string name, long length = 0) : base(name, length) { } + + public Int32DataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal Int32DataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/Int64DataFrameColumn.cs b/src/Microsoft.Data.Analysis/Int64DataFrameColumn.cs new file mode 100644 index 0000000000..f955404152 --- /dev/null +++ b/src/Microsoft.Data.Analysis/Int64DataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class Int64DataFrameColumn : PrimitiveDataFrameColumn + { + public Int64DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public Int64DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public Int64DataFrameColumn(string name, long length = 0) : base(name, length) { } + + public Int64DataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal Int64DataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj b/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj index 71490c0883..7071a50700 100644 --- a/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj +++ b/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj @@ -11,6 +11,14 @@ Initial preview of robust and extensible types and algorithms for manipulating structured data that supports aggregations, statistical funtions, sorting, grouping, joins, merges, handling missing values and more. ML.NET ML Machine Learning Data Science DataFrame Preparation DataView Analytics Exploration + + + + True + True + Converters.tt + + @@ -22,6 +30,14 @@ + + TextTemplatingFileGenerator + Converters.cs + + + TextTemplatingFileGenerator + DataFrameColumn.BinaryOperations.ExplodedColumns.cs + TextTemplatingFileGenerator DataFrameColumn.BinaryOperations.cs @@ -50,10 +66,23 @@ TextTemplatingFileGenerator ColumnArithmeticTemplate.cs + + TextTemplatingFileGenerator + PrimitiveDataFrameColumn.BinaryOperations.Combinations.ttinclude + + + True + True + PrimitiveDataFrameColumn.BinaryOperations.Combinations.tt + TextTemplatingFileGenerator PrimitiveDataFrameColumn.BinaryOperations.cs + + TextTemplatingFileGenerator + PrimitiveDataFrameColumn.BinaryOperators.cs + TextTemplatingFileGenerator PrimitiveDataFrameColumn.Computations.cs @@ -89,6 +118,16 @@ + + True + True + ColumnArithmeticTemplate.ttinclude + + + True + True + Converters.tt + True True @@ -124,6 +163,11 @@ True PrimitiveDataFrameColumn.BinaryOperations.tt + + True + True + PrimitiveDataFrameColumn.BinaryOperators.tt + True True diff --git a/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs b/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs index 767200a818..45521c137e 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveColumnContainer.cs @@ -617,6 +617,46 @@ internal PrimitiveColumnContainer CloneAsBoolContainer() return ret; } + internal PrimitiveColumnContainer CloneAsByteContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(ByteConverter.Instance.GetByte(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsSByteContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(SByteConverter.Instance.GetSByte(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + internal PrimitiveColumnContainer CloneAsDoubleContainer() { var ret = new PrimitiveColumnContainer(); @@ -656,5 +696,145 @@ internal PrimitiveColumnContainer CloneAsDecimalContainer() ret.NullCount = NullCount; return ret; } + + internal PrimitiveColumnContainer CloneAsShortContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(ShortConverter.Instance.GetShort(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsUShortContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(UShortConverter.Instance.GetUShort(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsIntContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(IntConverter.Instance.GetInt(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsUIntContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(UIntConverter.Instance.GetUInt(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsLongContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(LongConverter.Instance.GetLong(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsULongContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(ULongConverter.Instance.GetULong(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } + + internal PrimitiveColumnContainer CloneAsFloatContainer() + { + var ret = new PrimitiveColumnContainer(); + foreach (ReadOnlyDataFrameBuffer buffer in Buffers) + { + ret.Length += buffer.Length; + DataFrameBuffer newBuffer = new DataFrameBuffer(); + ret.Buffers.Add(newBuffer); + newBuffer.EnsureCapacity(buffer.Length); + ReadOnlySpan span = buffer.ReadOnlySpan; + for (int i = 0; i < span.Length; i++) + { + newBuffer.Append(FloatConverter.Instance.GetFloat(span[i])); + } + } + ret.NullBitMapBuffers = CloneNullBitMapBuffers(); + ret.NullCount = NullCount; + return ret; + } } } diff --git a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs index cf6e6d2b8f..18a9903342 100644 --- a/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs +++ b/src/Microsoft.Data.Analysis/PrimitiveDataFrameColumn.cs @@ -429,22 +429,77 @@ public PrimitiveDataFrameColumn Clone(IEnumerable mapIndices) return ret; } - internal PrimitiveDataFrameColumn CloneAsBoolColumn() + internal BooleanDataFrameColumn CloneAsBoolColumn() { PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsBoolContainer(); - return new PrimitiveDataFrameColumn(Name, newColumnContainer); + return new BooleanDataFrameColumn(Name, newColumnContainer); } - internal PrimitiveDataFrameColumn CloneAsDoubleColumn() + internal ByteDataFrameColumn CloneAsByteColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsByteContainer(); + return new ByteDataFrameColumn(Name, newColumnContainer); + } + + internal SByteDataFrameColumn CloneAsSByteColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsSByteContainer(); + return new SByteDataFrameColumn(Name, newColumnContainer); + } + + internal DoubleDataFrameColumn CloneAsDoubleColumn() { PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsDoubleContainer(); - return new PrimitiveDataFrameColumn(Name, newColumnContainer); + return new DoubleDataFrameColumn(Name, newColumnContainer); } - internal PrimitiveDataFrameColumn CloneAsDecimalColumn() + internal DecimalDataFrameColumn CloneAsDecimalColumn() { PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsDecimalContainer(); - return new PrimitiveDataFrameColumn(Name, newColumnContainer); + return new DecimalDataFrameColumn(Name, newColumnContainer); + } + + internal Int16DataFrameColumn CloneAsShortColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsShortContainer(); + return new Int16DataFrameColumn(Name, newColumnContainer); + } + + + internal UInt16DataFrameColumn CloneAsUShortColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsUShortContainer(); + return new UInt16DataFrameColumn(Name, newColumnContainer); + } + + internal Int32DataFrameColumn CloneAsIntColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsIntContainer(); + return new Int32DataFrameColumn(Name, newColumnContainer); + } + + internal UInt32DataFrameColumn CloneAsUIntColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsUIntContainer(); + return new UInt32DataFrameColumn(Name, newColumnContainer); + } + + internal Int64DataFrameColumn CloneAsLongColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsLongContainer(); + return new Int64DataFrameColumn(Name, newColumnContainer); + } + + internal UInt64DataFrameColumn CloneAsULongColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsULongContainer(); + return new UInt64DataFrameColumn(Name, newColumnContainer); + } + + internal SingleDataFrameColumn CloneAsFloatColumn() + { + PrimitiveColumnContainer newColumnContainer = _columnContainer.CloneAsFloatContainer(); + return new SingleDataFrameColumn(Name, newColumnContainer); } public override GroupBy GroupBy(int columnIndex, DataFrame parent) diff --git a/src/Microsoft.Data.Analysis/SByteDataFrameColumn.cs b/src/Microsoft.Data.Analysis/SByteDataFrameColumn.cs new file mode 100644 index 0000000000..731614da72 --- /dev/null +++ b/src/Microsoft.Data.Analysis/SByteDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class SByteDataFrameColumn : PrimitiveDataFrameColumn + { + public SByteDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public SByteDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public SByteDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public SByteDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal SByteDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/SingleDataFrameColumn.cs b/src/Microsoft.Data.Analysis/SingleDataFrameColumn.cs new file mode 100644 index 0000000000..e6be6255d0 --- /dev/null +++ b/src/Microsoft.Data.Analysis/SingleDataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class SingleDataFrameColumn : PrimitiveDataFrameColumn + { + public SingleDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public SingleDataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public SingleDataFrameColumn(string name, long length = 0) : base(name, length) { } + + public SingleDataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal SingleDataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/UInt16DataFrameColumn.cs b/src/Microsoft.Data.Analysis/UInt16DataFrameColumn.cs new file mode 100644 index 0000000000..e56cdca7f3 --- /dev/null +++ b/src/Microsoft.Data.Analysis/UInt16DataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class UInt16DataFrameColumn : PrimitiveDataFrameColumn + { + public UInt16DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public UInt16DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public UInt16DataFrameColumn(string name, long length = 0) : base(name, length) { } + + public UInt16DataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal UInt16DataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/UInt32DataFrameColumn.cs b/src/Microsoft.Data.Analysis/UInt32DataFrameColumn.cs new file mode 100644 index 0000000000..af114ff41e --- /dev/null +++ b/src/Microsoft.Data.Analysis/UInt32DataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class UInt32DataFrameColumn : PrimitiveDataFrameColumn + { + public UInt32DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public UInt32DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public UInt32DataFrameColumn(string name, long length = 0) : base(name, length) { } + + public UInt32DataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal UInt32DataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/src/Microsoft.Data.Analysis/UInt64DataFrameColumn.cs b/src/Microsoft.Data.Analysis/UInt64DataFrameColumn.cs new file mode 100644 index 0000000000..cb74704319 --- /dev/null +++ b/src/Microsoft.Data.Analysis/UInt64DataFrameColumn.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Data.Analysis +{ + public partial class UInt64DataFrameColumn : PrimitiveDataFrameColumn + { + public UInt64DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public UInt64DataFrameColumn(string name, IEnumerable values) : base(name, values) { } + + public UInt64DataFrameColumn(string name, long length = 0) : base(name, length) { } + + public UInt64DataFrameColumn(string name, ReadOnlyMemory buffer, ReadOnlyMemory nullBitMap, int length = 0, int nullCount = 0) : base(name, buffer, nullBitMap, length, nullCount) { } + + internal UInt64DataFrameColumn(string name, PrimitiveColumnContainer values) : base(name, values) { } + } +} diff --git a/tests/Microsoft.Data.Analysis.Tests/DataFrameTests.cs b/tests/Microsoft.Data.Analysis.Tests/DataFrameTests.cs index bdf383425e..f715dfa17d 100644 --- a/tests/Microsoft.Data.Analysis.Tests/DataFrameTests.cs +++ b/tests/Microsoft.Data.Analysis.Tests/DataFrameTests.cs @@ -16,8 +16,8 @@ public partial class DataFrameTests { public static DataFrame MakeDataFrameWithTwoColumns(int length, bool withNulls = true) { - DataFrameColumn dataFrameColumn1 = new PrimitiveDataFrameColumn("Int1", Enumerable.Range(0, length).Select(x => x)); - DataFrameColumn dataFrameColumn2 = new PrimitiveDataFrameColumn("Int2", Enumerable.Range(10, length).Select(x => x)); + DataFrameColumn dataFrameColumn1 = new Int32DataFrameColumn("Int1", Enumerable.Range(0, length).Select(x => x)); + DataFrameColumn dataFrameColumn2 = new Int32DataFrameColumn("Int2", Enumerable.Range(10, length).Select(x => x)); if (withNulls) { dataFrameColumn1[length / 2] = null; @@ -83,7 +83,7 @@ public static DataFrame MakeDataFrameWithAllColumnTypes(int length, bool withNul public static DataFrame MakeDataFrameWithAllMutableColumnTypes(int length, bool withNulls = true) { DataFrame df = MakeDataFrameWithNumericAndStringColumns(length, withNulls); - DataFrameColumn boolColumn = new PrimitiveDataFrameColumn("Bool", Enumerable.Range(0, length).Select(x => x % 2 == 0)); + DataFrameColumn boolColumn = new BooleanDataFrameColumn("Bool", Enumerable.Range(0, length).Select(x => x % 2 == 0)); df.Columns.Insert(df.Columns.Count, boolColumn); if (withNulls) { @@ -95,7 +95,7 @@ public static DataFrame MakeDataFrameWithAllMutableColumnTypes(int length, bool public static DataFrame MakeDataFrameWithNumericAndBoolColumns(int length) { DataFrame df = MakeDataFrameWithNumericColumns(length); - DataFrameColumn boolColumn = new PrimitiveDataFrameColumn("Bool", Enumerable.Range(0, length).Select(x => x % 2 == 0)); + DataFrameColumn boolColumn = new BooleanDataFrameColumn("Bool", Enumerable.Range(0, length).Select(x => x % 2 == 0)); df.Columns.Insert(df.Columns.Count, boolColumn); boolColumn[length / 2] = null; return df; @@ -104,14 +104,14 @@ public static DataFrame MakeDataFrameWithNumericAndBoolColumns(int length) public static DataFrame MakeDataFrameWithNumericAndStringColumns(int length, bool withNulls = true) { DataFrame df = MakeDataFrameWithNumericColumns(length, withNulls); - DataFrameColumn stringColumn = DataFrameColumn.Create("String", Enumerable.Range(0, length).Select(x => x.ToString())); + DataFrameColumn stringColumn = new StringDataFrameColumn("String", Enumerable.Range(0, length).Select(x => x.ToString())); df.Columns.Insert(df.Columns.Count, stringColumn); if (withNulls) { stringColumn[length / 2] = null; } - DataFrameColumn charColumn = DataFrameColumn.Create("Char", Enumerable.Range(0, length).Select(x => (char)(x + 65))); + DataFrameColumn charColumn = new CharDataFrameColumn("Char", Enumerable.Range(0, length).Select(x => (char)(x + 65))); df.Columns.Insert(df.Columns.Count, charColumn); if (withNulls) { @@ -122,17 +122,17 @@ public static DataFrame MakeDataFrameWithNumericAndStringColumns(int length, boo public static DataFrame MakeDataFrameWithNumericColumns(int length, bool withNulls = true) { - DataFrameColumn byteColumn = DataFrameColumn.Create("Byte", Enumerable.Range(0, length).Select(x => (byte)x)); - DataFrameColumn decimalColumn = DataFrameColumn.Create("Decimal", Enumerable.Range(0, length).Select(x => (decimal)x)); - DataFrameColumn doubleColumn = DataFrameColumn.Create("Double", Enumerable.Range(0, length).Select(x => (double)x)); - DataFrameColumn floatColumn = DataFrameColumn.Create("Float", Enumerable.Range(0, length).Select(x => (float)x)); - DataFrameColumn intColumn = DataFrameColumn.Create("Int", Enumerable.Range(0, length).Select(x => x)); - DataFrameColumn longColumn = DataFrameColumn.Create("Long", Enumerable.Range(0, length).Select(x => (long)x)); - DataFrameColumn sbyteColumn = DataFrameColumn.Create("Sbyte", Enumerable.Range(0, length).Select(x => (sbyte)x)); - DataFrameColumn shortColumn = DataFrameColumn.Create("Short", Enumerable.Range(0, length).Select(x => (short)x)); - DataFrameColumn uintColumn = DataFrameColumn.Create("Uint", Enumerable.Range(0, length).Select(x => (uint)x)); - DataFrameColumn ulongColumn = DataFrameColumn.Create("Ulong", Enumerable.Range(0, length).Select(x => (ulong)x)); - DataFrameColumn ushortColumn = DataFrameColumn.Create("Ushort", Enumerable.Range(0, length).Select(x => (ushort)x)); + DataFrameColumn byteColumn = new ByteDataFrameColumn("Byte", Enumerable.Range(0, length).Select(x => (byte)x)); + DataFrameColumn decimalColumn = new DecimalDataFrameColumn("Decimal", Enumerable.Range(0, length).Select(x => (decimal)x)); + DataFrameColumn doubleColumn = new DoubleDataFrameColumn("Double", Enumerable.Range(0, length).Select(x => (double)x)); + DataFrameColumn floatColumn = new SingleDataFrameColumn("Float", Enumerable.Range(0, length).Select(x => (float)x)); + DataFrameColumn intColumn = new Int32DataFrameColumn("Int", Enumerable.Range(0, length).Select(x => x)); + DataFrameColumn longColumn = new Int64DataFrameColumn("Long", Enumerable.Range(0, length).Select(x => (long)x)); + DataFrameColumn sbyteColumn = new SByteDataFrameColumn("Sbyte", Enumerable.Range(0, length).Select(x => (sbyte)x)); + DataFrameColumn shortColumn = new Int16DataFrameColumn("Short", Enumerable.Range(0, length).Select(x => (short)x)); + DataFrameColumn uintColumn = new UInt32DataFrameColumn("Uint", Enumerable.Range(0, length).Select(x => (uint)x)); + DataFrameColumn ulongColumn = new UInt64DataFrameColumn("Ulong", Enumerable.Range(0, length).Select(x => (ulong)x)); + DataFrameColumn ushortColumn = new UInt16DataFrameColumn("Ushort", Enumerable.Range(0, length).Select(x => (ushort)x)); DataFrame dataFrame = new DataFrame(new List { byteColumn, decimalColumn, doubleColumn, floatColumn, intColumn, longColumn, sbyteColumn, shortColumn, uintColumn, ulongColumn, ushortColumn }); @@ -197,7 +197,7 @@ public void TestIndexer() var row = dataFrame.Rows[4]; Assert.Equal(14, (int)row[1]); - var column = dataFrame["Int2"] as PrimitiveDataFrameColumn; + var column = dataFrame["Int2"] as Int32DataFrameColumn; Assert.Equal(1000, (int)column[2]); Assert.Throws(() => dataFrame["Int5"]); @@ -206,8 +206,8 @@ public void TestIndexer() [Fact] public void ColumnAndTableCreationTest() { - DataFrameColumn intColumn = new PrimitiveDataFrameColumn("IntColumn", Enumerable.Range(0, 10).Select(x => x)); - DataFrameColumn floatColumn = new PrimitiveDataFrameColumn("FloatColumn", Enumerable.Range(0, 10).Select(x => (float)x)); + DataFrameColumn intColumn = new Int32DataFrameColumn("IntColumn", Enumerable.Range(0, 10).Select(x => x)); + DataFrameColumn floatColumn = new SingleDataFrameColumn("FloatColumn", Enumerable.Range(0, 10).Select(x => (float)x)); DataFrame dataFrame = new DataFrame(); dataFrame.Columns.Insert(0, intColumn); dataFrame.Columns.Insert(1, floatColumn); @@ -218,17 +218,17 @@ public void ColumnAndTableCreationTest() Assert.Equal(10, dataFrame.Columns[1].Length); Assert.Equal("FloatColumn", dataFrame.Columns[1].Name); - DataFrameColumn bigColumn = new PrimitiveDataFrameColumn("BigColumn", Enumerable.Range(0, 11).Select(x => (float)x)); - DataFrameColumn repeatedName = new PrimitiveDataFrameColumn("FloatColumn", Enumerable.Range(0, 10).Select(x => (float)x)); + DataFrameColumn bigColumn = new SingleDataFrameColumn("BigColumn", Enumerable.Range(0, 11).Select(x => (float)x)); + DataFrameColumn repeatedName = new SingleDataFrameColumn("FloatColumn", Enumerable.Range(0, 10).Select(x => (float)x)); Assert.Throws(() => dataFrame.Columns.Insert(2, bigColumn)); Assert.Throws(() => dataFrame.Columns.Insert(2, repeatedName)); Assert.Throws(() => dataFrame.Columns.Insert(10, repeatedName)); Assert.Equal(2, dataFrame.Columns.Count); - DataFrameColumn intColumnCopy = new PrimitiveDataFrameColumn("IntColumn", Enumerable.Range(0, 10).Select(x => x)); + DataFrameColumn intColumnCopy = new Int32DataFrameColumn("IntColumn", Enumerable.Range(0, 10).Select(x => x)); Assert.Throws(() => dataFrame.Columns[1] = intColumnCopy); - DataFrameColumn differentIntColumn = new PrimitiveDataFrameColumn("IntColumn1", Enumerable.Range(0, 10).Select(x => x)); + DataFrameColumn differentIntColumn = new Int32DataFrameColumn("IntColumn1", Enumerable.Range(0, 10).Select(x => x)); dataFrame.Columns[1] = differentIntColumn; Assert.True(object.ReferenceEquals(differentIntColumn, dataFrame.Columns[1])); @@ -247,7 +247,7 @@ public void ColumnAndTableCreationTest() public void InsertAndRemoveColumnTests() { DataFrame dataFrame = MakeDataFrameWithAllMutableColumnTypes(10); - DataFrameColumn intColumn = new PrimitiveDataFrameColumn("IntColumn", Enumerable.Range(0, 10).Select(x => x)); + DataFrameColumn intColumn = new Int32DataFrameColumn("IntColumn", Enumerable.Range(0, 10).Select(x => x)); DataFrameColumn charColumn = dataFrame["Char"]; int insertedIndex = dataFrame.Columns.Count; dataFrame.Columns.Insert(dataFrame.Columns.Count, intColumn); @@ -390,7 +390,7 @@ public void TestBinaryOperationsWithConversions() // int + bool should throw Assert.Throws(() => df.Add(true)); - var dataFrameColumn1 = new PrimitiveDataFrameColumn("Double1", Enumerable.Range(0, 10).Select(x => (double)x)); + var dataFrameColumn1 = new DoubleDataFrameColumn("Double1", Enumerable.Range(0, 10).Select(x => (double)x)); df.Columns[0] = dataFrameColumn1; // Double + comparison ops should throw Assert.Throws(() => df.And(true)); @@ -400,8 +400,8 @@ public void TestBinaryOperationsWithConversions() public void TestBinaryOperationsOnBoolColumn() { var df = new DataFrame(); - var dataFrameColumn1 = new PrimitiveDataFrameColumn("Bool1", Enumerable.Range(0, 10).Select(x => true)); - var dataFrameColumn2 = new PrimitiveDataFrameColumn("Bool2", Enumerable.Range(0, 10).Select(x => true)); + var dataFrameColumn1 = new BooleanDataFrameColumn("Bool1", Enumerable.Range(0, 10).Select(x => true)); + var dataFrameColumn2 = new BooleanDataFrameColumn("Bool2", Enumerable.Range(0, 10).Select(x => true)); df.Columns.Insert(0, dataFrameColumn1); df.Columns.Insert(1, dataFrameColumn2); @@ -623,8 +623,8 @@ public void TestBinaryOperatorsWithConversions() public void TestBinaryOperatorsOnBoolColumns() { var df = new DataFrame(); - var dataFrameColumn1 = new PrimitiveDataFrameColumn("Bool1", Enumerable.Range(0, 10).Select(x => x % 2 == 0 ? true : false)); - var dataFrameColumn2 = new PrimitiveDataFrameColumn("Bool2", Enumerable.Range(0, 10).Select(x => x % 2 == 0 ? true : false)); + var dataFrameColumn1 = new BooleanDataFrameColumn("Bool1", Enumerable.Range(0, 10).Select(x => x % 2 == 0 ? true : false)); + var dataFrameColumn2 = new BooleanDataFrameColumn("Bool2", Enumerable.Range(0, 10).Select(x => x % 2 == 0 ? true : false)); df.Columns.Insert(0, dataFrameColumn1); df.Columns.Insert(1, dataFrameColumn2); @@ -668,7 +668,7 @@ public void TestBinaryOperatorsOnBoolColumns() [Fact] public void TestBinaryOperationsOnColumns() { - PrimitiveDataFrameColumn column = new PrimitiveDataFrameColumn("Int", Enumerable.Range(0, 10)); + Int32DataFrameColumn column = new Int32DataFrameColumn("Int", Enumerable.Range(0, 10)); Assert.ThrowsAny(() => column.Add(5.5, inPlace: true)); Assert.ThrowsAny(() => column.ReverseAdd(5.5, inPlace: true)); string str = "A String"; @@ -679,7 +679,7 @@ public void TestBinaryOperationsOnColumns() [Fact] public void TestColumnReverseOrderState() { - var column = new PrimitiveDataFrameColumn("Int", Enumerable.Range(0, 10)); + var column = new Int32DataFrameColumn("Int", Enumerable.Range(0, 10)); var newColumn = 1 - column; var checkOrderColumn = 1 - newColumn; Assert.True(checkOrderColumn.ElementwiseEquals(column).All()); @@ -935,13 +935,13 @@ public void TestStringColumnSort() public void TestPrimitiveColumnSort(int numberOfNulls) { // Primitive Column Sort - PrimitiveDataFrameColumn intColumn = new PrimitiveDataFrameColumn("Int", 0); + Int32DataFrameColumn intColumn = new Int32DataFrameColumn("Int", 0); Assert.Equal(0, intColumn.NullCount); intColumn.AppendMany(null, numberOfNulls); Assert.Equal(numberOfNulls, intColumn.NullCount); // Should handle all nulls - PrimitiveDataFrameColumn sortedIntColumn = intColumn.Sort() as PrimitiveDataFrameColumn; + PrimitiveDataFrameColumn sortedIntColumn = intColumn.Sort(); Assert.Equal(numberOfNulls, sortedIntColumn.NullCount); Assert.Null(sortedIntColumn[0]); @@ -952,19 +952,19 @@ public void TestPrimitiveColumnSort(int numberOfNulls) Assert.Equal(numberOfNulls, intColumn.NullCount); // Ascending sort - sortedIntColumn = intColumn.Sort() as PrimitiveDataFrameColumn; + sortedIntColumn = intColumn.Sort(); Assert.Equal(0, sortedIntColumn[0]); Assert.Null(sortedIntColumn[9]); // Descending sort - sortedIntColumn = intColumn.Sort(false) as PrimitiveDataFrameColumn; + sortedIntColumn = intColumn.Sort(ascending: false); Assert.Equal(4, sortedIntColumn[0]); Assert.Null(sortedIntColumn[9]); } private void VerifyJoin(DataFrame join, DataFrame left, DataFrame right, JoinAlgorithm joinAlgorithm) { - PrimitiveDataFrameColumn mapIndices = new PrimitiveDataFrameColumn("map", join.Rows.Count); + Int64DataFrameColumn mapIndices = new Int64DataFrameColumn("map", join.Rows.Count); for (long i = 0; i < join.Rows.Count; i++) { mapIndices[i] = i; @@ -1379,7 +1379,7 @@ public void TestIEnumerable() } Assert.Equal("foofoofoofoofoofoofoofoofoo", actualStrings.ToString()); - PrimitiveDataFrameColumn floatColumn = (PrimitiveDataFrameColumn)df["Float"]; + SingleDataFrameColumn floatColumn = (SingleDataFrameColumn)df["Float"]; actualStrings.Clear(); foreach (float? value in floatColumn) { @@ -1394,7 +1394,7 @@ public void TestIEnumerable() } Assert.Equal("012346789", actualStrings.ToString()); - PrimitiveDataFrameColumn intColumn = (PrimitiveDataFrameColumn)df["Int"]; + Int32DataFrameColumn intColumn = (Int32DataFrameColumn)df["Int"]; actualStrings.Clear(); foreach (int? value in intColumn) { @@ -1808,7 +1808,7 @@ public void TestValueCounts() public void TestApplyElementwiseNullCount() { DataFrame df = MakeDataFrameWithTwoColumns(10); - PrimitiveDataFrameColumn column = df["Int1"] as PrimitiveDataFrameColumn; + Int32DataFrameColumn column = df["Int1"] as Int32DataFrameColumn; Assert.Equal(1, column.NullCount); // Change all existing values to null @@ -1850,7 +1850,7 @@ public void TestClone(int dfLength, int intDfLength) { DataFrame df = MakeDataFrameWithAllColumnTypes(dfLength, withNulls: true); DataFrame intDf = MakeDataFrameWithTwoColumns(intDfLength, false); - PrimitiveDataFrameColumn intColumn = intDf["Int1"] as PrimitiveDataFrameColumn; + Int32DataFrameColumn intColumn = intDf["Int1"] as Int32DataFrameColumn; DataFrame clone = df[intColumn]; Assert.Equal(intDfLength, clone.Rows.Count); Assert.Equal(df.Columns.Count, clone.Columns.Count); @@ -1869,7 +1869,7 @@ public void TestClone(int dfLength, int intDfLength) public void TestColumnCreationFromExisitingColumn() { DataFrame df = MakeDataFrameWithAllColumnTypes(10); - PrimitiveDataFrameColumn bigInts = new PrimitiveDataFrameColumn("BigInts", df["Int"].ElementwiseGreaterThan(5)); + BooleanDataFrameColumn bigInts = new BooleanDataFrameColumn("BigInts", df["Int"].ElementwiseGreaterThan(5)); for (int i = 0; i < 10; i++) { if (i <= 5) @@ -2126,7 +2126,7 @@ public void TestAppendEmptyValue() public void TestApply() { int[] values = { 1, 2, 3, 4, 5 }; - var col = new PrimitiveDataFrameColumn("Ints", values); + var col = new Int32DataFrameColumn("Ints", values); PrimitiveDataFrameColumn newCol = col.Apply(i => i + 0.5d); Assert.Equal(values.Length, newCol.Length); @@ -2137,5 +2137,44 @@ public void TestApply() Assert.Equal(newCol[i], values[i] + 0.5d); } } + + [Fact] + public void TestDataFrameCreate() + { + int length = 10; + void AssertLengthTypeAndValues(DataFrameColumn column, Type type) + { + Assert.Equal(column.DataType, type); + Assert.Equal(length, column.Length); + for (long i = 0; i < column.Length; i++) + { + Assert.Equal(i.ToString(), column[i].ToString()); + } + } + DataFrameColumn stringColumn = DataFrameColumn.Create("String", Enumerable.Range(0, length).Select(x => x.ToString())); + AssertLengthTypeAndValues(stringColumn, typeof(string)); + DataFrameColumn byteColumn = DataFrameColumn.Create("Byte", Enumerable.Range(0, length).Select(x => (byte)x)); + AssertLengthTypeAndValues(byteColumn, typeof(byte)); + DataFrameColumn decimalColumn = DataFrameColumn.Create("Decimal", Enumerable.Range(0, length).Select(x => (decimal)x)); + AssertLengthTypeAndValues(decimalColumn, typeof(decimal)); + DataFrameColumn doubleColumn = DataFrameColumn.Create("Double", Enumerable.Range(0, length).Select(x => (double)x)); + AssertLengthTypeAndValues(doubleColumn, typeof(double)); + DataFrameColumn floatColumn = DataFrameColumn.Create("Float", Enumerable.Range(0, length).Select(x => (float)x)); + AssertLengthTypeAndValues(floatColumn, typeof(float)); + DataFrameColumn intColumn = DataFrameColumn.Create("Int", Enumerable.Range(0, length).Select(x => x)); + AssertLengthTypeAndValues(intColumn, typeof(int)); + DataFrameColumn longColumn = DataFrameColumn.Create("Long", Enumerable.Range(0, length).Select(x => (long)x)); + AssertLengthTypeAndValues(longColumn, typeof(long)); + DataFrameColumn sbyteColumn = DataFrameColumn.Create("Sbyte", Enumerable.Range(0, length).Select(x => (sbyte)x)); + AssertLengthTypeAndValues(sbyteColumn, typeof(sbyte)); + DataFrameColumn shortColumn = DataFrameColumn.Create("Short", Enumerable.Range(0, length).Select(x => (short)x)); + AssertLengthTypeAndValues(shortColumn, typeof(short)); + DataFrameColumn uintColumn = DataFrameColumn.Create("Uint", Enumerable.Range(0, length).Select(x => (uint)x)); + AssertLengthTypeAndValues(uintColumn, typeof(uint)); + DataFrameColumn ulongColumn = DataFrameColumn.Create("Ulong", Enumerable.Range(0, length).Select(x => (ulong)x)); + AssertLengthTypeAndValues(ulongColumn, typeof(ulong)); + DataFrameColumn ushortColumn = DataFrameColumn.Create("Ushort", Enumerable.Range(0, length).Select(x => (ushort)x)); + AssertLengthTypeAndValues(ushortColumn, typeof(ushort)); + } } }