如何将二维字符串向量的一行提取为双精度向量?
How to extract one row of a 2D string vector to vector of double?
我有计算移动平均线的函数:
void MovingAverage(double inputSeries[]
, size_t inputSize, size_t window, float* output )
我的计算思路:
- 构造一个循环,每次取出一行
vec2D
- 使用
MovingAverage
函数获取输出
第一步,从 csv 文件解析二维向量:
std::vector<std::vector<std::string>> vec2D{
{"S0001","01","02","03"}, {"S0002","11","12","13"}, {"S0003","21","22","23"}
};
我想提取此二维向量的一行(比如第二行)并将该行存储为一维向量std::vector<double> copyRow
然后计算每一行的移动平均值。
copyRow = {11,12,13}
我尝试了 vector<double> copyRow(vec2D[0].begin(), vec2D[0].end());
但它不起作用,因为二维矢量是 std::string
类型。
我也试过循环:
int rowN = vec2D.size();
int colN = vec2D[0].size();
double num;
for (int i = 0; i < rowN; i++)
{
for (int j = 0; j < colN; j++)
{
num = stod(vec2D[i][j]);
copyRow[i][j].push_back(num);
}
}
但是它将所有行中的所有值附加到向量中。执行此操作的最佳方法是什么?
I tried vector<double> copyRow(vec2D[0].begin(), vec2D[0].end());
but it doesn't work because the 2D vector is string type.
您可以使用 <algorithm>
中的算法函数 std::transform
来执行此操作。
由于每行的第一个元素无法转换为 double
,您可以通过开始迭代器之后的一个元素开始跳过它:
#include <algorithm> // std::transform
std::vector<double> copyRow;
// reserve memory for unwanted real locations
copyRow.reserve(vec2D[1].size() - 1u);
std::transform(std::cbegin(vec2D[1]) + 1, std::cend(vec2D[1])
, std::back_inserter(copyRow), [](const auto& ele) {
return std::stod(ele);
});
在主线程中的评论之后,似乎初始数据结构(字符串的二维向量)似乎不是最佳选择。
相反,std::map
或 std::unordered_map
等关联容器似乎更适合您要完成的任务。基本上,映射的键是非数字字段,数据将是与键关联的 vector<double>
。
然后,在给定键值的情况下,只需获取对双打行的引用即可。
下面是说明这一点的代码示例:
#include <map>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
std::string test = "S0001,01,02,03,S0002,11,12,13,S0003,21,22,23";
int main()
{
std::map<std::string, std::vector<double>> mymap;
int numCols = 4;
int count = 0;
std::istringstream strm(test);
std::string data;
std::string id;
while(std::getline(strm, data, ','))
{
if ( count % numCols == 0)
id = data;
else
mymap[id].push_back(stod(data));
++count;
}
for (auto& m : mymap)
{
std::cout << "\n" << m.first << "\n";
for (auto& v : m.second)
std::cout << " " << v << "\n";
}
// Get the vector associated with S0002
std::cout << "\nHere is the data for S0002:" << "\n";
std::vector<double>& vDouble = mymap["S0002"];
for (auto& d : vDouble)
std::cout << d << " ";
}
输出:
S0001
1
2
3
S0002
11
12
13
S0003
21
22
23
Here is the data for S0002:
11 12 13
主要有两点:
字符串向量不再成为问题,因为在 std::vector<double>
元素的填充中,对字符串调用 std::stod
以将字符串转换为双.
访问 std::vector<double>
变得微不足道——您需要做的就是获取密钥(字符串数据)并访问(在本例中通过引用),与钥匙。没有复制,没有 std::transform
调用,或类似的东西。
我有计算移动平均线的函数:
void MovingAverage(double inputSeries[]
, size_t inputSize, size_t window, float* output )
我的计算思路:
- 构造一个循环,每次取出一行
vec2D
- 使用
MovingAverage
函数获取输出
第一步,从 csv 文件解析二维向量:
std::vector<std::vector<std::string>> vec2D{
{"S0001","01","02","03"}, {"S0002","11","12","13"}, {"S0003","21","22","23"}
};
我想提取此二维向量的一行(比如第二行)并将该行存储为一维向量std::vector<double> copyRow
然后计算每一行的移动平均值。
copyRow = {11,12,13}
我尝试了 vector<double> copyRow(vec2D[0].begin(), vec2D[0].end());
但它不起作用,因为二维矢量是 std::string
类型。
我也试过循环:
int rowN = vec2D.size();
int colN = vec2D[0].size();
double num;
for (int i = 0; i < rowN; i++)
{
for (int j = 0; j < colN; j++)
{
num = stod(vec2D[i][j]);
copyRow[i][j].push_back(num);
}
}
但是它将所有行中的所有值附加到向量中。执行此操作的最佳方法是什么?
I tried
vector<double> copyRow(vec2D[0].begin(), vec2D[0].end());
but it doesn't work because the 2D vector is string type.
您可以使用 <algorithm>
中的算法函数 std::transform
来执行此操作。
由于每行的第一个元素无法转换为 double
,您可以通过开始迭代器之后的一个元素开始跳过它:
#include <algorithm> // std::transform
std::vector<double> copyRow;
// reserve memory for unwanted real locations
copyRow.reserve(vec2D[1].size() - 1u);
std::transform(std::cbegin(vec2D[1]) + 1, std::cend(vec2D[1])
, std::back_inserter(copyRow), [](const auto& ele) {
return std::stod(ele);
});
在主线程中的评论之后,似乎初始数据结构(字符串的二维向量)似乎不是最佳选择。
相反,std::map
或 std::unordered_map
等关联容器似乎更适合您要完成的任务。基本上,映射的键是非数字字段,数据将是与键关联的 vector<double>
。
然后,在给定键值的情况下,只需获取对双打行的引用即可。
下面是说明这一点的代码示例:
#include <map>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
std::string test = "S0001,01,02,03,S0002,11,12,13,S0003,21,22,23";
int main()
{
std::map<std::string, std::vector<double>> mymap;
int numCols = 4;
int count = 0;
std::istringstream strm(test);
std::string data;
std::string id;
while(std::getline(strm, data, ','))
{
if ( count % numCols == 0)
id = data;
else
mymap[id].push_back(stod(data));
++count;
}
for (auto& m : mymap)
{
std::cout << "\n" << m.first << "\n";
for (auto& v : m.second)
std::cout << " " << v << "\n";
}
// Get the vector associated with S0002
std::cout << "\nHere is the data for S0002:" << "\n";
std::vector<double>& vDouble = mymap["S0002"];
for (auto& d : vDouble)
std::cout << d << " ";
}
输出:
S0001
1
2
3
S0002
11
12
13
S0003
21
22
23
Here is the data for S0002:
11 12 13
主要有两点:
字符串向量不再成为问题,因为在
std::vector<double>
元素的填充中,对字符串调用std::stod
以将字符串转换为双.访问
std::vector<double>
变得微不足道——您需要做的就是获取密钥(字符串数据)并访问(在本例中通过引用),与钥匙。没有复制,没有std::transform
调用,或类似的东西。