From 9632a12d64110eb701ecc42a48ca8d86cc62fd3e Mon Sep 17 00:00:00 2001 From: jmbeamer <34815244+jmbeamer@users.noreply.github.com> Date: Thu, 28 May 2020 17:36:31 -0400 Subject: [PATCH 1/3] Loading new DataFrame with IDataReader Utilizes IDataReader.GetSchemaTable() to deduce column names and types, then reads rows into the DataFrame --- src/Microsoft.Data.Analysis/DataFrame.IO.cs | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/Microsoft.Data.Analysis/DataFrame.IO.cs b/src/Microsoft.Data.Analysis/DataFrame.IO.cs index 084b66379da..308e1b5634b 100644 --- a/src/Microsoft.Data.Analysis/DataFrame.IO.cs +++ b/src/Microsoft.Data.Analysis/DataFrame.IO.cs @@ -306,5 +306,72 @@ public static DataFrame LoadCsv(Stream csvStream, return ret; } } + + /// + /// Reads an implementation of IDataReader into a DataFrame. + /// + /// DataReader to be read in + /// number of rows to read not including the header(if present) + /// add one column with the row index + /// + public static DataFrame FromDataReader(IDataReader reader, string[] columnNames = null, Type[] dataTypes = null, long numberOfRowsToRead = -1, bool addIndexColumn = false) + { + DataTable schemaTable = reader.GetSchemaTable(); + int numberOfColumns = schemaTable.Rows.Count; + + if (columnNames == null) + { + columnNames = new string[numberOfColumns]; + for (int i = 0; i < numberOfColumns; ++i) + { + string columnName = schemaTable.Rows[i]["ColumnName"].ToString(); + columnNames[i] = string.IsNullOrWhiteSpace(columnName) ? $"Column{i}" : columnName; + } + } + + var columns = new List(numberOfColumns); + if (dataTypes == null) + { + for (int i = 0; i < numberOfColumns; ++i) + { + var kind = (Type)schemaTable.Rows[i]["DataType"]; + columns.Add(CreateColumn(kind, columnNames, i)); + } + } + else + { + for (int i = 0; i < numberOfColumns; ++i) + { + columns.Add(CreateColumn(dataTypes[i], columnNames, i)); + } + } + + long rowline = 0; + var ret = new DataFrame(columns); + while (reader.Read() && (numberOfRowsToRead == -1 || rowline < numberOfRowsToRead)) + { + ret.Append(GetRecordValues(reader), inPlace: true); + ++rowline; + } + + if (addIndexColumn) + { + PrimitiveDataFrameColumn indexColumn = new PrimitiveDataFrameColumn("IndexColumn", columns[0].Length); + for (int i = 0; i < columns[0].Length; i++) + { + indexColumn[i] = i; + } + columns.Insert(0, indexColumn); + } + return ret; + + IEnumerable GetRecordValues(IDataRecord record) + { + for (int i = 0; i < record.FieldCount; i++) + { + yield return record[i] == DBNull.Value ? null : record[i]; + } + } + } } } From 49534e1dd567256337389bcace658f6e3d59cddd Mon Sep 17 00:00:00 2001 From: jmbeamer <34815244+jmbeamer@users.noreply.github.com> Date: Thu, 28 May 2020 17:37:49 -0400 Subject: [PATCH 2/3] Fixed missing XML doc --- src/Microsoft.Data.Analysis/DataFrame.IO.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Microsoft.Data.Analysis/DataFrame.IO.cs b/src/Microsoft.Data.Analysis/DataFrame.IO.cs index 308e1b5634b..1bf8e013169 100644 --- a/src/Microsoft.Data.Analysis/DataFrame.IO.cs +++ b/src/Microsoft.Data.Analysis/DataFrame.IO.cs @@ -311,6 +311,8 @@ public static DataFrame LoadCsv(Stream csvStream, /// Reads an implementation of IDataReader into a DataFrame. /// /// DataReader to be read in + /// column names (can be empty) + /// column types (can be empty) /// number of rows to read not including the header(if present) /// add one column with the row index /// From 68e147d8a8b7dd1e270411cc6cc2a1bf301c7280 Mon Sep 17 00:00:00 2001 From: jmbeamer <34815244+jmbeamer@users.noreply.github.com> Date: Thu, 28 May 2020 17:45:17 -0400 Subject: [PATCH 3/3] Missing dependency on System.Data --- src/Microsoft.Data.Analysis/DataFrame.IO.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.Data.Analysis/DataFrame.IO.cs b/src/Microsoft.Data.Analysis/DataFrame.IO.cs index 1bf8e013169..9a6a9154341 100644 --- a/src/Microsoft.Data.Analysis/DataFrame.IO.cs +++ b/src/Microsoft.Data.Analysis/DataFrame.IO.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Data; using System.IO; using System.Text;