我正在创建一个自定义DataSet,但我受到一些限制:
我不知道DataSet中将存储哪种类型的数据,因此我最初的想法是将其设为List
object
,但我怀疑频繁使用数据和打字的需求将非常昂贵。
基本理念是:
class DataSet : IDataSet
{
private Dictionary<string, List<Object>> _data;
/// <summary>
/// Constructs the data set given the user-specified labels.
/// </summary>
/// <param name="labels">
/// The labels of each column in the data set.
/// </param>
public DataSet(List<string> labels)
{
_data = new Dictionary<string, List<object>>();
foreach (string label in labels)
{
_data.Add(label, new List<object>());
}
}
#region IDataSet Members
public List<string> DataLabels
{
get { return _data.Keys.ToList(); }
}
public int Count
{
get { _data[_data.Keys[0]].Count; }
}
public List<object> GetValues(string label)
{
return _data[label];
}
public object GetValue(string label, int index)
{
return _data[label][index];
}
public void InsertValue(string label, object value)
{
_data[label].Insert(0, value);
}
public void AddValue(string label, object value)
{
_data[label].Add(value);
}
#endregion
}
将使用DataSet
的具体示例是存储从CSV
文件获取的数据,其中第一列包含标签。从CSV
文件加载数据时,我想指定类型而不是转换为object
。数据可能包含日期,数字,字符串等列。以下是它的样子:
"Date","Song","Rating","AvgRating","User"
"02/03/2010","Code Monkey",4.6,4.1,"joe"
"05/27/2009","Code Monkey",1.2,4.5,"jill"
数据将用于机器学习/人工智能算法,因此我必须非常快速地读取数据。我想尽可能地消除类型转换,因为我不能从'object'转换为每次读取时需要的任何数据类型。
我见过允许用户为csv文件中的每个项目选择特定数据类型的应用程序,所以我试图制作一个类似的解决方案,其中可以为每个列指定不同的类型。我想创建一个通用的解决方案,所以我不必返回List<object>
而是List<DateTime>
(如果它是DateTime列)或List<double>
(如果它是双列的列)。
有什么方法可以实现这一目标吗?也许我的方法是错误的,有没有更好的方法解决这个问题?
答案 0 :(得分:2)
我建议您尝试现在拥有的东西。也许表现会很好。如果没有,只有这样,你才能考虑进一步优化。
您还可以将每个字段存储为变体对象,如下所示:
struct Variant
{
string StringValue;
DateTime DateTimeValue;
bool BoolValue;
// ... etc. ...
}
然后你只需要从结构中访问适当的成员,但是这可能会增加内存使用和if语句的开销......
答案 1 :(得分:2)
请记住,DataSet还将行,列等存储为对象。让它们输入类型通常意味着在您键入的数据集中完成转换。
我认为这实际上取决于从csv读取数据会发生什么,但是为了在不事先知道您需要哪种类型的情况下消除转换,我只能想到通过Reflection.Emit动态创建保存数据的类型。
正如杰夫所说,但是施法可能不会杀死你的应用。