C++如何实现读取CSV后将单个DataFrame按类别拆分为多个DataFrame
C++ 实现按类别拆分CSV为独立DataFrame
实现逻辑
- 逐行读取解析CSV内容,自动识别表头和数据行
- 以指定分类列为key,通过哈希表维护不同类别对应的独立DataFrame
- 遍历数据行按分类值归入对应DataFrame,最终可直接按分类取对应结构化数据
- 以下实现无第三方依赖,自定义简易DataFrame结构,兼容逗号、空格两种常见CSV分隔符
完整实现代码
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <unordered_map> // 自定义简易DataFrame结构 struct DataFrame { std::vector<std::string> columns; // 存储列名 std::vector<std::vector<std::string>> rows; // 存储所有行数据 // 打印DataFrame内容,用于结果校验 void print() const { // 打印表头 for (size_t i = 0; i < columns.size(); i++) { std::cout << columns[i]; if (i != columns.size() - 1) std::cout << "\t"; } std::cout << "\n"; // 逐行打印数据 for (const auto& row : rows) { for (size_t i = 0; i < row.size(); i++) { std::cout << row[i]; if (i != row.size() - 1) std::cout << "\t"; } std::cout << "\n"; } } }; // 按分隔符拆分字符串的工具函数,自动去除字段前后空格 std::vector<std::string> split(const std::string& s, char delimiter) { std::vector<std::string> tokens; std::string token; std::istringstream tokenStream(s); while (std::getline(tokenStream, token, delimiter)) { size_t start = token.find_first_not_of(" "); size_t end = token.find_last_not_of(" "); if (start != std::string::npos) { tokens.push_back(token.substr(start, end - start + 1)); } } return tokens; } int main() { const std::string csv_path = "your_file.csv"; // 替换为实际CSV文件路径 const char delimiter = ','; // 空格分隔的CSV改为' '即可 const std::string group_col = "fruit"; // 指定用于分组的列名 std::ifstream file(csv_path); if (!file.is_open()) { std::cerr << "无法打开目标CSV文件" << std::endl; return 1; } std::string line; // 读取并解析表头 std::getline(file, line); std::vector<std::string> columns = split(line, delimiter); // 定位分组列的索引位置 int group_col_idx = -1; for (size_t i = 0; i < columns.size(); i++) { if (columns[i] == group_col) { group_col_idx = i; break; } } if (group_col_idx == -1) { std::cerr << "CSV中不存在指定的分组列" << std::endl; return 1; } // 按分组存储DataFrame:key为分类值,value为对应类别的独立DataFrame std::unordered_map<std::string, DataFrame> group_dfs; while (std::getline(file, line)) { if (line.empty()) continue; // 跳过空行 std::vector<std::string> row = split(line, delimiter); std::string group_key = row[group_col_idx]; // 首次出现的分类先初始化表头 if (group_dfs.find(group_key) == group_dfs.end()) { group_dfs[group_key].columns = columns; } group_dfs[group_key].rows.push_back(row); } file.close(); // 输出拆分结果 int df_idx = 1; for (const auto& pair : group_dfs) { std::cout << "dataframe " << df_idx << ":\n"; pair.second.print(); std::cout << "\n"; df_idx++; } return 0; }
使用说明
- 将代码中
csv_path变量替换为实际CSV文件的本地路径 - 若CSV和示例格式一致,使用多空格作为字段分隔符,将
delimiter变量值改为' '即可 - 若需要更换分组维度,修改
group_col变量为目标列名即可 - 代码默认以字符串类型存储所有字段,若需要做数值计算,可在解析行时将对应字段转为int/double类型存储
运行输出效果
程序运行后输出的拆分结果和预期完全一致:
dataframe 1: fruit time price apple 2022 18 apple 2023 19 dataframe 2: fruit time price banana 2022 30 banana 2023 32
内容的提问来源于stack exchange,提问作者inv inv
相关产品推荐
相关产品推荐

