问题
I m using ILNumerics to read and write from/to matfiles. I get some data from a database as object[,] because it contains numbers and headings (strings).
The data structure of object[,] loaddata
is a mixture of System.String
and System.Double
, first two columns and first row contains strings rest doubles. I want to write the doubles into the matfile. Dimensions are roughly loaddata[9000,500]
.
This is my very cumbersome detour via system arrays that doesnt even work:
ILArray<object> loaddata = DBQuery(....);
//this next line has error
var tempoobj = ToSystemMatrix<object>(loaddata["2:end", "1:end"]);
double[,] tempdouble = new double[500, 8784];
Array.Copy(tempoobj, tempdouble, tempoobj.Length);
ILArray<double> B = tempdouble;
using (ILMatFile matW = new ILMatFile())
{
B.Name = "power";
matW.AddArray(B);
matW.Write(@"C:\Temp\Test.mat");
}
with the ToSystemMatrix function from here How to convert ILArray into double[,] array? - which I couldnt make work.
any ideas how to simplify this? and also how to make that function work (as it is usefull anyways).
UPDATE
I made this work but it feels like going at it with a sledgehammer.... But here it comes:
object[,] loaddata = DBQuery(...);
for (int i = 0; i < loaddata.GetLength(0); i++)
{
loaddata[i, 0] = Convert.ToDouble(0);
loaddata[i, 1] = Convert.ToDouble(0);
}
for (int i = 0; i < loaddata.GetLength(1); i++)
{
loaddata[0, i] = Convert.ToDouble(0);
}
double[,] tempdouble = new double[loaddata.GetLength(0), loaddata.GetLength(1)];
Array.Copy(loaddata, tempdouble, loaddata.Length);
ILArray<double> B = tempdouble;
using (ILMatFile matW = new ILMatFile())
{
B.Name = "power";
matW.AddArray(B["1:end","2:end"].T);
matW.Write(@"C:\Temp\Test.mat");
}
I also tried to use ILCell instead but ILCell loaddata = DBQuery(...)
and cell(loaddata)
threw errors.
Any ideas how to make this more neat?
回答1:
Consider rethinking your design. In order to return multiple information from DBQuery(....)
you could either utilize ILCell
or some other data structure which is able to store typed information about your headers and elements (let's say DataTable). Just object[,] seems too general.
Since I don't have specific information about your setup, I'll give one example for ILCell
:
using ILNumerics;
using System;
namespace Cell_DBQuery_Example {
class Program {
static void Main(string[] args) {
using (ILScope.Enter()) {
ILCell data = Helper.DBQuery();
// data is:
//Cell [2,2]
//[0]: <String> header 1 <Double> [100,200]
//[1]: <String> header 2 <Single> [2,3000]
// store into mat file
ILMatFile mat = new ILMatFile();
var key1 = (string)data.GetArray<string>(0, 0);
mat.AddArray(data.GetArray<double>(0, 1), key1); // stores rand(100,200) as key: "header1"
// proceed with other columns...
// write mat file
mat.Write("filename");
}
}
class Helper : ILMath {
public static ILRetCell DBQuery() {
using (ILScope.Enter()) {
// prepare return cell
ILCell ret = cell(size(2, 2));
// todo: fetch data from db and replace below example data
ret[0, 0] = "header_1";
ret[1, 0] = "header_2";
ret[0, 1] = rand(100, 200);
ret[1, 1] = ones<float>(2, 3000);
return ret;
}
}
}
}
}
This creates and returns a cell in the Helper
class. The cell contains the header and numeric data in seperate cell elements. It is than be used to retrieve the information from the cell and stores them into a mat file.
Some references: http://ilnumerics.net/Cells.html
http://ilnumerics.net/GeneralRules.html - general rules for ILNumerics functions
http://ilnumerics.net/hdf5-interface.html - more options of writing compatible formats: HDF5
回答2:
Change this line:
var tempoobj = ToSystemMatrix<object>(loaddata["2:end", "1:end"]);
to
var tempoobj = ToSystemMatrix<double>(loaddata["2:end", "1:end"]);
This assumes that you've selected only the part of loaddata where all the data are doubles.
来源:https://stackoverflow.com/questions/26038344/how-to-convert-ilarrayobject-into-ilarraydouble