从tsv中读取100k+行的特定行数据,仅使用标准库
Read specific row of data from tsv with 100k+ lines, using standard libraries only
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。是制表符分隔的,不包含空格或自由行等,即:
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行和大量列。第一列是一个唯一的标识符(Integer, [0,…]),我想使用它来访问与它相关的参数值。一般来说,"ConfigID"的编号应该是重要的。我事先不知道列数
我正在寻找一个函数,该函数将在头读入字符串向量和相应的数据,对应于键,进入双向量(相同的排序)。这应该在没有任何特殊库的情况下完成,因为我不知道如何链接它们…此外,我会欣赏一个非常简单的结构,没有类/模板等工作。就像
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]
小后续:然后我想通过循环访问向量中的数据,将值从我用于模拟(模拟开发实验室)的"语言"传递给一些宏。因此,我还想将字符串"转换"为字符。这可以通过添加"。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也是标签[]和参数[]的一部分是可以的
鉴于我缺乏编程经验,我过去的"解决"方法是编写一个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;
}
让我们来谈谈你的数据结构:
- 标签必须与包含
double
的结构分开保存,否则您将最终获得n-相同标签的副本。我们把标签放在容器vector<string> Labels
- 如果你的键列是连续的,从1开始,简单地把你的双子星放在
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);
}
<<p> 生活例子/kbd> 相关文章:
- 如何知道用于实现标准代码段的确切数据结构和算法,例如在C++STL中?
- 标准 cpp 数据结构和线程互斥锁?
- 是否有一个标准函数可以打印/监视stdin文件的内容,同时将数据留在stdin中
- 访问位域联合是C++标准中常见的初始数据未定义行为
- 如何在不复制数据的情况下将 cv::Mat 转换为 2d 标准::矢量
- C++11 标准中的哪一部分规定了基元数据类型大小之间的相对顺序?
- 标准地图如何知道使用标准字符串的数据作为键
- uint32, int16, uint8 .为什么这些常用的数据类型没有进入标准
- 使用标准库或Boost库从一组数据中计算直方图
- 哪个C 标准包括要添加到对象文件中的文件强制代码 /数据
- 组合来自多个线程的数据的标准方法?
- C++标准是否允许复制任意多态数据结构?
- 从另一个命名空间访问标准命名空间数据成员
- 将临时值存储为某种数据类型时,算术运算的标准规则是什么
- 如何通过套接字传输标准::多映射数据
- 如何在不注册对象的情况下访问标准项模型的数据?
- 将字节数组转换为标准数据类型
- C++"使用"运算符使标准数据障碍的对象可用
- 构建图的最佳标准数据结构是什么?
- 定义一个行为类似于标准c++数据类型的新数据类型