/// <summary> /// Convert pandas DataFrame to <see cref="DataTable"/> /// </summary> /// <param name="pyObject">Pandas DataFrame object</param> /// <returns>Result table</returns> public static DataTable DataFrameToDataTable(dynamic pyObject) { if (pyObject == null) { throw new ArgumentNullException(nameof(pyObject)); } using (var utilities = new PythonUtils()) { if (!utilities.IsDataFrame(pyObject)) { throw new ArgumentException("Object is not a pandas dataframe", nameof(pyObject)); } //Define columns info var columnNames = utilities.GetDataFrameColumnNames(pyObject); var columns = new ColumnInfo[columnNames.Length]; for (var i = 0; i < columns.Length; i++) { var name = columnNames[i]; var type = utilities.GetTypeCode(pyObject, i); columns[i] = new ColumnInfo(utilities, name, type); } //Define result table columns var dataTable = new DataTable("Result"); foreach (var column in columns) { var name = column.Name; var dataColumn = new DataColumn(name) { Caption = name, DataType = column.ManagedType, AllowDBNull = true }; dataTable.Columns.Add(dataColumn); } //Iterate for each row var rowCount = ((PyObject)pyObject.index).Length(); for (long i = 0; i < rowCount; i++) { var row = dataTable.NewRow(); for (var j = 0; j < columns.Length; j++) { var column = columns[j]; var pyValue = utilities.GetDataFrameItem(pyObject, i, j); var value = pyValue == null ? null : column.GetManagedValue(pyValue); row[j] = value ?? DBNull.Value; } dataTable.Rows.Add(row); } return(dataTable); } }
/// <summary> /// Create an instance of <see cref="ColumnInfo"/> /// </summary> /// <param name="utils">Python utilities</param> /// <param name="name">Column name</param> /// <param name="pyType">Column type</param> public ColumnInfo(PythonUtils utils, string name, PyType pyType) { _utils = utils ?? throw new ArgumentNullException(nameof(utils)); if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name can't be null or empty", nameof(name)); } Name = name; PythonType = pyType; switch (PythonType) { case PyType.Undefined: ManagedType = typeof(string); break; case PyType.BoolType: ManagedType = typeof(bool); break; case PyType.Int8Type: ManagedType = typeof(sbyte); break; case PyType.Uint8Type: ManagedType = typeof(byte); break; case PyType.Int16Type: ManagedType = typeof(short); break; case PyType.Uint16Type: ManagedType = typeof(ushort); break; case PyType.Uint32Type: ManagedType = typeof(uint); break; case PyType.Int64Type: ManagedType = typeof(long); break; case PyType.Uint64Type: ManagedType = typeof(ulong); break; case PyType.Int32Type: ManagedType = typeof(int); break; case PyType.Float16Type: ManagedType = typeof(float); break; case PyType.Float32Type: ManagedType = typeof(float); break; case PyType.Float64Type: ManagedType = typeof(double); break; case PyType.Complex128Type: ManagedType = typeof(string); break; case PyType.Complex64Type: ManagedType = typeof(string); break; case PyType.ObjectType: ManagedType = typeof(string); break; case PyType.Datetime64Type: ManagedType = typeof(DateTime); break; case PyType.Timedelta64Type: ManagedType = typeof(TimeSpan); break; default: throw new ArgumentOutOfRangeException(); } }