技术求助:将波士顿房价数据集列转为2D float向量行并分离最后一列
解决C++读取波士顿房价数据集的实现方案
核心代码实现
首先实现字符串分割函数,用于处理制表符分隔的字段:
#include <iostream> #include <fstream> #include <vector> #include <sstream> #include <string> #include <stdexcept> using namespace std; vector<string> split(const string& s, char delim) { vector<string> tokens; string token; istringstream tokenStream(s); while (getline(tokenStream, token, delim)) { if (!token.empty()) { tokens.push_back(token); } } return tokens; }
然后实现文件读取函数,收集所有数据行:
vector<vector<float>> read_all_rows(const string& filename) { vector<vector<float>> data; ifstream file(filename); if (!file.is_open()) { cerr << "无法打开文件: " << filename << endl; return data; } string line; // 跳过表头(数据集第一行通常是列名,无数据则注释此行) getline(file, line); while (getline(file, line)) { vector<string> tokens = split(line, '\t'); vector<float> row; try { for (const string& token : tokens) { row.push_back(stof(token)); } } catch (const invalid_argument& e) { cerr << "字段转换失败: " << token << " 不是有效数值" << endl; return {}; } catch (const out_of_range& e) { cerr << "字段数值超出范围: " << token << endl; return {}; } if (!row.empty()) { data.push_back(row); } } file.close(); return data; }
按需求处理数据(列转2D vector行 + 单独存储最后一列)
int main() { string filename = "boston_housing.txt"; // 替换为你的数据集文件路径 auto all_data = read_all_rows(filename); if (all_data.empty()) { return 1; } int num_cols = all_data[0].size(); if (num_cols < 2) { cerr << "数据集列数不足,无法分离特征与标签" << endl; return 1; } // 每一列作为2D vector的一行 vector<vector<float>> feature_columns(num_cols - 1); vector<float> labels; for (const auto& row : all_data) { // 填充特征列向量 for (int i = 0; i < num_cols - 1; ++i) { feature_columns[i].push_back(row[i]); } // 提取最后一列作为标签 labels.push_back(row.back()); } // 验证输出(可根据需要删除) cout << "特征列总数: " << feature_columns.size() << endl; cout << "第一特征列的首个数值: " << feature_columns[0][0] << endl; cout << "标签总数: " << labels.size() << endl; cout << "首个标签值: " << labels[0] << endl; return 0; }
补充:常规机器学习样本格式(行作为样本)
如果你的实际需求是每行作为一个样本(2D vector的行是单个样本的所有特征),可替换main函数中的数据处理部分为:
int main() { string filename = "boston_housing.txt"; auto all_data = read_all_rows(filename); if (all_data.empty()) { return 1; } vector<vector<float>> features; vector<float> labels; for (const auto& row : all_data) { // 提取当前行前n-1个字段作为特征 vector<float> sample_features(row.begin(), row.end() - 1); features.push_back(sample_features); // 提取最后一个字段作为标签 labels.push_back(row.back()); } // 验证输出 cout << "样本总数: " << features.size() << endl; cout << "单个样本特征数: " << features[0].size() << endl; cout << "标签总数: " << labels.size() << endl; return 0; }
注意事项
- 确保数据集文件是制表符分隔,如果是逗号分隔,将
split函数中的分隔符改为',' - 如果数据集没有表头,删除
read_all_rows函数中跳过表头的getline(file, line);语句 - 处理大文件时可优化内存占用,避免一次性读取所有行(按需逐行处理并填充目标向量)
内容的提问来源于stack exchange,提问作者mchaudh4
相关产品推荐
相关产品推荐

