diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml new file mode 100644 index 0000000..f8e5ff5 --- /dev/null +++ b/.github/workflows/macos-ci.yml @@ -0,0 +1,26 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: MacOS Build and Test +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + #- name: Test + # run: dotnet test --no-build --verbosity normal \ No newline at end of file diff --git a/.github/workflows/ubuntu-ci.yml b/.github/workflows/ubuntu-ci.yml new file mode 100644 index 0000000..779c6ce --- /dev/null +++ b/.github/workflows/ubuntu-ci.yml @@ -0,0 +1,26 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: Ubuntu Build and Test +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal \ No newline at end of file diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml new file mode 100644 index 0000000..6c6ab72 --- /dev/null +++ b/.github/workflows/windows-ci.yml @@ -0,0 +1,26 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: Windows Build and Test +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6b6006e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/test/Pandas.NET.Test/bin/Debug/net8.0/Pandas.NET.Test.dll", + "args": [], + "cwd": "${workspaceFolder}/test/Pandas.NET.Test", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..5fd1dbd --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Pandas.NET.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Pandas.NET.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/Pandas.NET.sln" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/ci-build/mac-ci-pipeline.yml b/ci-build/mac-ci-pipeline.yml deleted file mode 100644 index 55b9ca1..0000000 --- a/ci-build/mac-ci-pipeline.yml +++ /dev/null @@ -1,28 +0,0 @@ -pool: - vmImage: 'macOS-12' - -variables: - solution: '**/*.sln' - buildPlatform: 'Any CPU' - buildConfiguration: 'Release' - -steps: -- task: NuGetToolInstaller@1 - -- task: NuGetCommand@2 - inputs: - restoreSolution: '$(solution)' - -- task: DotNetCoreCLI@2 - inputs: - command: build - projects: '$(solution)' - configuration: '$(buildConfiguration)' - arguments: '--configuration $(buildConfiguration) -p:Platform="$(buildPlatform)"' - -- task: DotNetCoreCLI@2 - inputs: - command: test - projects: '$(solution)' - configuration: '$(buildConfiguration)' - arguments: '--configuration $(buildConfiguration) -p:Platform="$(buildPlatform)"' diff --git a/ci-build/ubuntu-ci-pipeline.yml b/ci-build/ubuntu-ci-pipeline.yml deleted file mode 100644 index 7ded755..0000000 --- a/ci-build/ubuntu-ci-pipeline.yml +++ /dev/null @@ -1,28 +0,0 @@ -pool: - vmImage: 'ubuntu-22.04' - -variables: - solution: '**/*.sln' - buildPlatform: 'Any CPU' - buildConfiguration: 'Release' - -steps: -- task: NuGetToolInstaller@1 - -- task: NuGetCommand@2 - inputs: - restoreSolution: '$(solution)' - -- task: DotNetCoreCLI@2 - inputs: - command: build - projects: '$(solution)' - configuration: '$(buildConfiguration)' - arguments: '--configuration $(buildConfiguration) -p:Platform="$(buildPlatform)"' - -- task: DotNetCoreCLI@2 - inputs: - command: test - projects: '$(solution)' - configuration: '$(buildConfiguration)' - arguments: '--configuration $(buildConfiguration) -p:Platform="$(buildPlatform)"' diff --git a/ci-build/win-ci-pipeline.yml b/ci-build/win-ci-pipeline.yml deleted file mode 100644 index 642fd51..0000000 --- a/ci-build/win-ci-pipeline.yml +++ /dev/null @@ -1,28 +0,0 @@ -pool: - vmImage: 'windows-2022' - -variables: - solution: '**/*.sln' - buildPlatform: 'Any CPU' - buildConfiguration: 'Release' - -steps: -- task: NuGetToolInstaller@1 - -- task: NuGetCommand@2 - inputs: - restoreSolution: '$(solution)' - -- task: DotNetCoreCLI@2 - inputs: - command: build - projects: '$(solution)' - configuration: '$(buildConfiguration)' - arguments: '--configuration $(buildConfiguration) -p:Platform="$(buildPlatform)"' - -- task: DotNetCoreCLI@2 - inputs: - command: test - projects: '$(solution)' - configuration: '$(buildConfiguration)' - arguments: '--configuration $(buildConfiguration) -p:Platform="$(buildPlatform)"' diff --git a/src/Pandas.NET/Columns/Column.cs b/src/Pandas.NET/Columns/Column.cs index 22481d7..32940a9 100644 --- a/src/Pandas.NET/Columns/Column.cs +++ b/src/Pandas.NET/Columns/Column.cs @@ -10,6 +10,17 @@ public class Column public string Name { get; set; } public Type DType { get; set; } + + public Column() + { + } + + public Column(string name, Type dtype) + { + Name = name; + DType = dtype; + } + public override string ToString() => $"{Name} {DType}"; } diff --git a/src/Pandas.NET/DataFrames/DataFrame.cs b/src/Pandas.NET/DataFrames/DataFrame.cs index fbb2c07..b9a05ea 100644 --- a/src/Pandas.NET/DataFrames/DataFrame.cs +++ b/src/Pandas.NET/DataFrames/DataFrame.cs @@ -45,6 +45,12 @@ public DataFrame(List data, Series index = null, List columns = index.size, columns.Count }; + + foreach (var s in _data) + { + s.SetIndex(_index); + } + } } } diff --git a/src/Pandas.NET/DataFrames/DataFrame.operator.cs b/src/Pandas.NET/DataFrames/DataFrame.operator.cs index 3bebe6c..d6bf53b 100644 --- a/src/Pandas.NET/DataFrames/DataFrame.operator.cs +++ b/src/Pandas.NET/DataFrames/DataFrame.operator.cs @@ -16,7 +16,9 @@ public partial class DataFrame { data.Add(a.data[i] - b.data switch { + double[] double64 => double64[i], float[] float32 => float32[i], + int[] int32 => int32[i], _ => throw new NotImplementedException("") }); } @@ -32,7 +34,9 @@ public partial class DataFrame { data.Add(a.data[i] / b.data switch { + double[] double64 => double64[i], float[] float32 => float32[i], + int[] int32 => int32[i], _ => throw new NotImplementedException("") }); } @@ -40,6 +44,16 @@ public partial class DataFrame return new DataFrame(data, index: a.index, columns: a.columns); } + public static DataFrame operator *(DataFrame a, Series b) + { + var data = new List(); + for(int i=0;i 0) { - excludeRowIndexArray[i] = rnd.Next(0, _index.size - 1); + n = (int)Math.Ceiling(frac * _index.size); } + if (n > _index.size) + { + throw new ArgumentException("n should be less than the size of the DataFrame"); + } + + // treat axis as 0 for now. support for axis=1 should be added in the future + var rnd = new Random(random_state); - var data = new List(); + // make a list that we can sample from + List sampleIndex = null; + + if(!replace){ + // randomize the index and take the first n elements, no duplicates + sampleIndex = Enumerable + .Range(0, _index.size) + .OrderBy(arg => rnd.Next()) + .Take(n).ToList(); + } + else{ + // for each sample, randomly select an index allowing duplicates + var sampleIndexes = Enumerable.Range(0, _index.size); + for (int i = 0; i < n; i++) + { + sampleIndex.Add(sampleIndexes.ElementAt(rnd.Next(0, sampleIndexes.Count()-1))); + } + } + + // initialize a dictionary to hold the data + Dictionary data = new Dictionary(); foreach (var s in _data) { - var series = s.drop(excludeRowIndexArray); - data.Add(series); + // init the array based on the dtype + ArrayList array =new ArrayList(); + data.Add(s.column, array); + } + + // fill the arrays with the sampled data + for (int i = 0; i < sampleIndex.Count; i++) + { + foreach (var s in _data) + { + data[s.column].Add(s.data.GetValue(sampleIndex[i])); + } } - var index = _index.array().Where(x => !excludeRowIndexArray.Contains(x)).ToArray(); - return new DataFrame(data, columns: _columns, index: new Series(index)); + + // create a new DataFrame with the sampled data + DataFrame df = new DataFrame(data.Select(x => new Series(x.Value.ToArray(x.Key.DType), x.Key)).ToList(), index: new Series(sampleIndex.ToArray())); + return df; + } } diff --git a/src/Pandas.NET/Pandas.NET.csproj b/src/Pandas.NET/Pandas.NET.csproj index 3e9fa8e..e496771 100644 --- a/src/Pandas.NET/Pandas.NET.csproj +++ b/src/Pandas.NET/Pandas.NET.csproj @@ -21,7 +21,7 @@ + - \ No newline at end of file diff --git a/src/Pandas.NET/Series/Series.operator.cs b/src/Pandas.NET/Series/Series.operator.cs index f5183d1..9e56c4b 100644 --- a/src/Pandas.NET/Series/Series.operator.cs +++ b/src/Pandas.NET/Series/Series.operator.cs @@ -5,21 +5,27 @@ namespace PandasNet { public partial class Series { - public static Series operator !=(Series a, float b) + public static Series operator !=(Series a, double b) { - if (a.data is float[] float32) - return new Series(float32.Select(x => x != b).ToArray()); - else if (a.data is double[] float64) - return new Series(float64.Select(x => x != b).ToArray()); + if (a.data is int[] || a.data is float[] || a.data is double[]) + { + return new Series(a.data.Cast().Select(x => x != b).ToArray() + , column: a._column + , index: a._index?.copy()); + } + throw new NotImplementedException(""); } - public static Series operator ==(Series a, float b) + public static Series operator ==(Series a, double b) { - if (a.data is float[] float32) - return new Series(float32.Select(x => x == b).ToArray()); - else if (a.data is double[] float64) - return new Series(float64.Select(x => x == b).ToArray()); + if (a.data is int[] || a.data is float[] || a.data is double[]) + { + return new Series(a.data.Cast().Select(x => x == b).ToArray() + , column: a._column + , index: a._index?.copy()); + } + throw new NotImplementedException(""); } @@ -42,42 +48,78 @@ public partial class Series throw new NotImplementedException(""); } - public static Series operator +(Series a, float b) + public static Series operator +(Series a, double b) { - if (a.data is float[] float32) - return new Series(float32.Select(x => x + b).ToArray()); - else if (a.data is double[] float64) - return new Series(float64.Select(x => x + b).ToArray()); + if (a.data is int[] || a.data is float[] || a.data is double[]) + { + return new Series(a.data.Cast().Select(x => x + b).ToArray() + , column: a._column + , index: a._index?.copy()); + } + throw new NotImplementedException(""); } - public static Series operator -(Series a, float b) + public static Series operator -(Series a, double b) { - if (a.data is float[] float32) - return new Series(float32.Select(x => x - b).ToArray()); - else if (a.data is double[] float64) - return new Series(float64.Select(x => x - b).ToArray()); - else if (a.data is int[] int32) - return new Series(int32.Select(x => x - b).ToArray()); + if (a.data is int[] || a.data is float[] || a.data is double[]) + { + return new Series(a.data.Cast().Select(x => x - b).ToArray() + , column: a._column + , index: a._index?.copy()); + } + throw new NotImplementedException(""); } - public static Series operator *(Series a, float b) + public static Series operator *(Series a, double b) { - if (a.data is float[] float32) - return new Series(float32.Select(x => x * b).ToArray()); - else if (a.data is double[] float64) - return new Series(float64.Select(x => x * b).ToArray()); + if (a.data is int[] || a.data is float[] || a.data is double[]) + { + return new Series(a.data.Cast().Select(x => x * b).ToArray() + , column: a._column + , index: a._index?.copy()); + } + throw new NotImplementedException(""); } - public static Series operator /(Series a, float b) + public static Series operator /(Series a, double b) { - if (a.data is float[] float32) - return new Series(float32.Select(x => x / b).ToArray()); - else if (a.data is double[] float64) - return new Series(float64.Select(x => x / b).ToArray()); + if (a.data is int[] || a.data is float[] || a.data is double[]) + { + return new Series(a.data.Cast().Select(x => x / b).ToArray() + , column: a._column + , index: a._index?.copy()); + } + throw new NotImplementedException(""); } + + public override bool Equals(object obj) + { + if (obj is Series series) + { + if (series.data is double[] double64) + { + return data.Cast().SequenceEqual(double64); + } + else if (series.data is float[] float32) + { + return data.Cast().SequenceEqual(float32); + } + else if (series.data is int[] int32) + { + return data.Cast().SequenceEqual(int32); + } + } + + return false; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } } diff --git a/test/Pandas.NET.Test/DataFrames/DataFrame.test.operator.cs b/test/Pandas.NET.Test/DataFrames/DataFrame.test.operator.cs new file mode 100644 index 0000000..04e309d --- /dev/null +++ b/test/Pandas.NET.Test/DataFrames/DataFrame.test.operator.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using HDF5CSharp; +using PandasNet; + + +namespace Pandas.Test; + +public class DataFrameOperatorTests +{ + [Fact] + public void TestSubtractionOperator() + { + // Arrange + List data = new List + { + new Series(new double[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(double) }), + new Series(new double[] { 2, 4, 6, 8, 10 }, new Column { Name = "column2", DType = typeof(double) }) + }; + var df = new DataFrame(data); + + var series = new Series(new double[] { 0.5, 1.5 }, new Series(new string[]{"column1","column2"}), new Column("sub", typeof(double))); + + // Act + var result = df - series; + + // Assert + Assert.Equal(new double[] { 0.5, 1.5, 2.5, 3.5, 4.5 }, result["column1"].data as double[]); + Assert.Equal(new double[] { 0.5, 2.5, 4.5, 6.5, 8.5}, result["column2"].data as double[]); + } + + [Fact] + public void TestDivisionOperator() + { + List data = new List + { + new Series(new double[] { 5, 10, 15, 20, 25 }, new Column { Name = "column1", DType = typeof(double) }), + new Series(new double[] { 2, 4, 6, 8, 10 }, new Column { Name = "column2", DType = typeof(double) }) + }; + var df = new DataFrame(data); + + var series = new Series(new double[] { 5, 2 }); + + // Act + var result = df / series; + + // Assert + Assert.Equal(new double[] { 1, 2, 3, 4, 5 }, result["column1"].data as double[]); + Assert.Equal(new double[] { 1, 2, 3, 4, 5 }, result["column2"].data as double[]); + } + + [Fact] + public void TestMultiplicationOperator() + { + List data = new List + { + new Series(new double[] { 5, 10, 15, 20, 25 }, new Column { Name = "column1", DType = typeof(double) }), + new Series(new double[] { 2, 4, 6, 8, 10 }, new Column { Name = "column2", DType = typeof(double) }) + }; + var df = new DataFrame(data); + + var series = new Series(new double[] { 1, 10 }); + + // Act + var result = df * series; + + // Assert + Assert.Equal(new double[] { 5, 10, 15, 20, 25 }, result["column1"].data as double[]); + Assert.Equal(new double[] { 20, 40, 60, 80, 100 }, result["column2"].data as double[]); + } + + [Fact] + public void TestEqualityOperator() + { + // Arrange + List data = new List + { + new Series(new float[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(float) }), + new Series(new float[] { 6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(float) }) + }; + var df = new DataFrame(data); + var df2 = new DataFrame(data); + + // Arrange: DataFrame with different column name + List badColumnData = new List + { + new Series(new float[] { 1, 2, 3, 4, 5 }, new Column { Name = "Column1", DType = typeof(float) }), + new Series(new float[] { 6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(float) }) + }; + var badColumnDf = new DataFrame(badColumnData); + // Arrange: DataFrame with different data + List badData = new List + { + new Series(new float[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(float) }), + new Series(new float[] { 6, 7, 8, 9, 11 }, new Column { Name = "column2", DType = typeof(float) }) + }; + + // Act + bool areEqual = df == df2; + bool badColumnInequal = df == badColumnDf; + bool badDataInequal = df == new DataFrame(badData); + + // Assert + Assert.True(areEqual); + Assert.False(badColumnInequal); + Assert.False(badDataInequal); + } + + [Fact] + public void TestInEqualityOperator() + { + // Arrange + List data = new List + { + new Series(new float[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(float) }), + new Series(new float[] { 6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(float) }) + }; + var df = new DataFrame(data); + var df2 = new DataFrame(data); + + // Arrange: DataFrame with different column name + List badColumnData = new List + { + new Series(new float[] { 1, 2, 3, 4, 5 }, new Column { Name = "Column1", DType = typeof(float) }), + new Series(new float[] { 6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(float) }) + }; + var badColumnDf = new DataFrame(badColumnData); + // Arrange: DataFrame with different data + List badData = new List + { + new Series(new float[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(float) }), + new Series(new float[] { 6, 7, 8, 9, 11 }, new Column { Name = "column2", DType = typeof(float) }) + }; + + // Act + bool areEqual = df != df2; + bool badColumnInequal = df != badColumnDf; + bool badDataInequal = df != new DataFrame(badData); + + // Assert + Assert.False(areEqual); + Assert.True(badColumnInequal); + Assert.True(badDataInequal); + } +} diff --git a/test/Pandas.NET.Test/DataFrames/DataFrame.test.pop.cs b/test/Pandas.NET.Test/DataFrames/DataFrame.test.pop.cs new file mode 100644 index 0000000..34095fc --- /dev/null +++ b/test/Pandas.NET.Test/DataFrames/DataFrame.test.pop.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using PandasNet; +using Tensorflow; + +namespace Pandas.Test; + +public class DataFramePopTest +{ + [Fact] + public void TestPopMethod() + { + // Arrange + var dataFrameData = new List(); + dataFrameData.Add(new Series(new float[] { 1, 2, 3, 4, 5 }, new Column("column1", typeof(float)))); + dataFrameData.Add(new Series(new float[] { 6, 7, 8, 9, 10 }, new Column("column2", typeof(float)))); + var dataFrame = new DataFrame(dataFrameData); + + // Act + var poppedSeries = dataFrame.pop("column1"); + + // Assert + Assert.True(poppedSeries.array().SequenceEqual([1, 2, 3, 4, 5])); + Assert.False(dataFrame.columns.Where(c => c.Name == "column1").Any()); + Assert.True(dataFrame.columns.Where(c => c.Name == "column2").Any()); + } +} \ No newline at end of file diff --git a/test/Pandas.NET.Test/DataFrames/DataFrame.test.sample.cs b/test/Pandas.NET.Test/DataFrames/DataFrame.test.sample.cs new file mode 100644 index 0000000..c4de814 --- /dev/null +++ b/test/Pandas.NET.Test/DataFrames/DataFrame.test.sample.cs @@ -0,0 +1,73 @@ +using PandasNet; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Pandas.Test; +public class DataFrameSampleTests +{ + [Fact] + public void TestSampleMethod() + { + // Arrange + List data = new List + { + new Series(new double[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(double) }), + new Series(new double[] {6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(double) }) + }; + var dataFrame = new DataFrame(data); + + // Act + var sampledDataFrame = dataFrame.sample(n: 3, random_state: 1); + + // Assert + Assert.Equal(3, sampledDataFrame.index.size); + Assert.True(sampledDataFrame.columns.Where(x => x.Name == "column1").Any()); + Assert.True(sampledDataFrame.columns.Where(x => x.Name == "column2").Any()); + } + + [Fact] + public void TestSampleMethodWithFrac() + { + // Arrange + List data = new List + { + new Series(new double[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(double) }), + new Series(new double[] {6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(double) }) + }; + var dataFrame = new DataFrame(data); + + // Act + var sampledDataFrame = dataFrame.sample(frac: 0.4f, random_state: 1); + var sampledDataFrame2 = dataFrame.sample(frac: 0.4f, random_state: 2); + + // Assert + Assert.Equal(2, sampledDataFrame.index.size); // 40% of 5 is 2 + Assert.True(sampledDataFrame.columns.Where(x => x.Name == "column1").Any()); + Assert.True(sampledDataFrame.columns.Where(x => x.Name == "column2").Any()); + Assert.Equal(2.0D, sampledDataFrame["column1"].GetValue(0)); + Assert.Equal(7.0D, sampledDataFrame["column2"].GetValue(0)); + + // assert for other state + Assert.Equal(2, sampledDataFrame2.index.size); // 40% of 5 is 2 + Assert.Equal(5.0D, sampledDataFrame2["column1"].GetValue(0)); + Assert.Equal(10.0D, sampledDataFrame2["column2"].GetValue(0)); + } + + [Fact] + public void TestSampleMethodThrowsException() + { + // Arrange + List data = new List + { + new Series(new double[] { 1, 2, 3, 4, 5 }, new Column { Name = "column1", DType = typeof(double) }), + new Series(new double[] {6, 7, 8, 9, 10 }, new Column { Name = "column2", DType = typeof(double) }) + }; + var dataFrame = new DataFrame(data); + + // Act & Assert + Assert.Throws(() => dataFrame.sample()); + Assert.Throws(() => dataFrame.sample(n: 3, frac: 0.4f)); + Assert.Throws(() => dataFrame.sample(n: 6)); + } +} \ No newline at end of file diff --git a/test/Pandas.NET.Test/Pandas.NET.Test.csproj b/test/Pandas.NET.Test/Pandas.NET.Test.csproj index e6a0115..e4a70ac 100644 --- a/test/Pandas.NET.Test/Pandas.NET.Test.csproj +++ b/test/Pandas.NET.Test/Pandas.NET.Test.csproj @@ -13,7 +13,6 @@ all - runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/PandasConsole/DataFrames/PandasConsole.indexers.cs b/test/PandasConsole/DataFrames/PandasConsole.indexers.cs index 59a558f..95114db 100644 --- a/test/PandasConsole/DataFrames/PandasConsole.indexers.cs +++ b/test/PandasConsole/DataFrames/PandasConsole.indexers.cs @@ -18,11 +18,11 @@ public DataFrame GetSampleDataFrame() return df; } - + // index on multiple columns public (DataFrame, DataFrame) MultiColumnIndexer() { var df = GetSampleDataFrame(); return (df, df["col_1","col_2"]); } } -} \ No newline at end of file +}