gpt4 book ai didi

c++ - 仅使用标准库从 100k+ 行的 tsv 中读取特定行的数据

转载 作者:行者123 更新时间:2023-11-30 05:21:02 26 4
gpt4 key购买 nike

Edit3 下面提供了最终解决方案。

我有一个具有以下结构的数据文件(它是一个用于模拟分析的设计点矩阵):

+----------+----------------------+-----------------+----------+----------+----------+-----------+-------------+
| ConfigID | k_StrategiesPerAgent | K_StrategySpace | l_Lambda | m_Memory | n_Agents | p_crowded | s_Seed |
+----------+----------------------+-----------------+----------+----------+----------+-----------+-------------+
| 0.0 | 0.0 | 0.0 | 0.5 | 12.0 | 10.0 | 0.2 | 353756906.0 |
| 1.0 | 0.0 | 0.2 | 0.5 | 12.0 | 10.0 | 0.2 | 923055597.0 |
| 2.0 | 0.0 | 0.4 | 0.5 | 12.0 | 10.0 | 0.2 | 616881203.0 |
+----------+----------------------+-----------------+----------+----------+----------+-----------+-------------+

文件 “DPM.tsv” 以制表符分隔,不包含空格或空行等,即:

ConfigID    k_StrategiesPerAgent    K_StrategySpace l_Lambda    m_Memory    n_Agents    p_crowded   s_Seed
0.0 0.0 0.0 0.5 12.0 10.0 0.2 353756906.0
1.0 0.0 0.2 0.5 12.0 10.0 0.2 923055597.0
2.0 0.0 0.4 0.5 12.0 10.0 0.2 616881203.0

它可能包含超过 100k 行和大量列。第一列是一个唯一标识符(整数,[0,...]),我想使用它来访问与其关联的参数值。一般来说,“ConfigID”的编号应该是连续的。事先不知道列数。

我正在寻找一个函数,它将在 header 中读入一个字符串 vector ,并将对应于键的相应数据读入一个 double vector (相同排序)。这应该在没有任何特殊库的情况下完成,因为我不知道如何链接它们......我也希望有一个非常简单的结构,它可以在没有类/模板等的情况下工作。像

vector<string> Labels; //Hold the parameter labels
vector<double> Parameters; //Hold the parameter values
bool readPars(char * FilePath, int ConfigID); //load the label and value
//return [false] on error, else [true]

小跟进:然后我想通过循环访问 vector 中的数据,将值传递给我用于模拟的“语言”中的某个宏 (laboratory for simulation development)。因此,我还想将字符串“转”为字符。这可以通过将“.c_str()”添加到字符串来完成,对吗?例如:

for (int i=0;i<Labels.size();i++){
const char * lab = Labels[i].c_str();
double par = Parameters[i];
LSD_MACRO(lab,par)//do something
}

ConfigID 也是 Labels[] 和 Parameters[] 的一部分很好

鉴于我缺乏编程经验,我过去“解决”这个问题的方法是编写一个 python 脚本,该脚本对一个包含所有数据的数组进行硬编码,然后我通过#include 将其包含在内……但是这样有局限性一个程序。

非常感谢! -弗雷德里克


解决方案:遵循 Jonathan Mee 的回答并加载所有内容。

using namespace std;
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
#include <iostream>
#include <limits>

int main()
{
const char * DPM_File = "DPM.tsv";
cout << DPM_File << endl;
ifstream fileP(DPM_File); //Read File in tsv format, with header-line

//read the header
string label;
getline(fileP, label, '\n');
//create a string vector with the header
istringstream gccNeedsThisOnASeperateLine{ label };
const vector<string> Labels{ istream_iterator<string>{ gccNeedsThisOnASeperateLine }, istream_iterator<string>{} };

//Read the remainer and parse it to a 2d vector of doubles
vector<vector<double>> Parameters;
do {
vector<double> input(Labels.size());
for(int i = 0; i < input.size(); i++){
fileP >> input[i];
}
if(!fileP.fail()) //control for empty line at end of file
Parameters.push_back(input);
} while(fileP.ignore(numeric_limits<streamsize>::max(), '\n'));

//Test:

for (int i=0;i<Labels.size();i++){
cout << Labels[i] << "\t" << Parameters[0][i] << endl;
}
cout << endl;

for (int i=0;i<Labels.size();i++){
cout << Labels[i] << "\t" << Parameters[5][i] << endl;
}
cout << endl;

int sssize = Parameters.size();
cout << "The sssize is" << sssize << endl;
for (int i=0;i<Labels.size();i++){
cout << Labels[i] << "\t" << Parameters[sssize-1][i] << endl;
}
cout << endl;

return 0;
}

最佳答案

让我们谈谈您的数据结构:

  1. 标签必须与包含您的 double 的结构分开存放否则,您最终会得到 n 个相同标签的拷贝。所以我们将把标签放在容器中 vector<string> Labels
  2. 如果您的键列从 1 开始是连续的,只需将您的 double 放在 vector<vector<double>> Parameters 中并且索引将用作从零开始的键,否则您需要使用 map<int, vector<double>> Parameters ,因为它更简单,我们假设数字是连续的并使用 vector<vector<double>> Parameters

鉴于您已成功将文件打开到 ifstream fileP你可以得到你的Labels像这样:

string label;

getline(fileP, label, '\n');

const vector<string> Labels{ istream_iterator<string>{ istringstream{ label } }, istream_iterator<string>{} };

认为有更好的方法,我们可以简单地使用嵌套 for -循环提取vector<vector<double>> Parameters :

while(fileP.ignore(std::numeric_limits<std::streamsize>::max(), '\t')) {
vector<double> input(size(Labels) - 1);

for(int i = 0; i < size(input) && fileP >> input[i]; ++i);
Parameters.push_back(input);
}

Live Example

关于c++ - 仅使用标准库从 100k+ 行的 tsv 中读取特定行的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40417867/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com