You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中如何将二维string数组转为double/int数组?求分类场景替代方案

嘿,这个内存错误确实挺闹心的,尤其是处理分类数据转数值格式的时候。先别急,咱们先搞清楚问题根源——你直接硬转字符串到数字肯定行不通,毕竟像"Sunny""Hot"这种分类标签根本不是数值类型,而且那个内存保护错误大概率是非法类型转换或者数组越界导致的。下面给你两种常用的分类数据转数值的靠谱实现,完全避开内存问题:

方案1:标签编码(Label Encoding)——适合有序分类

如果你的分类特征是有顺序的(比如温度的Hot > Warm > Cool),标签编码是个不错的选择,它会把每个唯一字符串映射成一个整数。

实现代码

首先写个工具方法生成每个列的字符串-整数映射:

private static Dictionary<string, int> CreateLabelMapping(string[] uniqueValues)
{
    var mapping = new Dictionary<string, int>();
    for (int i = 0; i < uniqueValues.Length; i++)
    {
        // 按唯一值出现顺序分配整数,有序分类可以手动调整顺序
        mapping[uniqueValues[i]] = i;
    }
    return mapping;
}

然后批量转换整个数据集:

string[] columnNames = { "Outlook", "Temperature", "Humidity", "Wind", "PlayTennis" };
string[][] data = { 
    new string[] { "Sunny", "Hot", "High", "Weak", "No" }, 
    new string[] { "Sunny", "Hot", "High", "Strong", "No" },
    // 补充你的完整数据
};

// 为每一列创建标签映射
var columnMappings = new Dictionary<string, Dictionary<string, int>>();
foreach (var columnName in columnNames)
{
    int columnIndex = Array.IndexOf(columnNames, columnName);
    // 获取该列所有唯一值
    var uniqueValues = data.Select(row => row[columnIndex]).Distinct().ToArray();
    columnMappings[columnName] = CreateLabelMapping(uniqueValues);
}

// 转换为int[][]数组
int[][] intData = new int[data.Length][];
for (int rowIdx = 0; rowIdx < data.Length; rowIdx++)
{
    intData[rowIdx] = new int[data[rowIdx].Length];
    for (int colIdx = 0; colIdx < data[rowIdx].Length; colIdx++)
    {
        var currentColumnName = columnNames[colIdx];
        // 通过映射安全转换
        intData[rowIdx][colIdx] = columnMappings[currentColumnName][data[rowIdx][colIdx]];
    }
}

方案2:独热编码(One-Hot Encoding)——适合无序分类

如果分类特征是无序的(比如Outlook的Sunny/Overcast/Rain,没有高低顺序),独热编码更合适,它会把每个分类转换成一个二进制数组,避免模型错误地认为标签有顺序。

实现代码

基于上面的标签映射,我们可以快速实现独热编码:

// 计算独热编码后的总特征长度
int totalFeatureCount = columnNames.Sum(col => 
{
    int colIdx = Array.IndexOf(columnNames, col);
    return data.Select(row => row[colIdx]).Distinct().Count();
});

// 初始化double[][]数组
double[][] oneHotData = new double[data.Length][];
for (int rowIdx = 0; rowIdx < data.Length; rowIdx++)
{
    oneHotData[rowIdx] = new double[totalFeatureCount];
    int currentFeaturePos = 0;
    
    for (int colIdx = 0; colIdx < columnNames.Length; colIdx++)
    {
        var colName = columnNames[colIdx];
        var labelMapping = columnMappings[colName];
        // 获取当前字符串对应的标签索引
        int labelIndex = labelMapping[data[rowIdx][colIdx]];
        // 独热编码置1
        oneHotData[rowIdx][currentFeaturePos + labelIndex] = 1.0;
        // 移动到下一列的独热起始位置
        currentFeaturePos += labelMapping.Count;
    }
}

关键注意事项

  • 处理缺失值:如果你的数据里有null或者空字符串,要先填充默认值(比如"Unknown")或者删除对应行,不然字典查找会抛出KeyNotFoundException
  • 测试数据复用映射:如果后续有测试数据,一定要用训练数据生成的映射,不能重新生成,避免标签不一致
  • 有序分类手动调整映射:比如温度Low < Medium < High,可以手动排序唯一值后再生成映射,保证整数顺序符合业务逻辑

内容的提问来源于stack exchange,提问作者Heights

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:34:56