如何将二维字符串向量的一行提取为双精度向量?

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 ) 

我的计算思路:

  1. 构造一个循环,每次取出一行vec2D
  2. 使用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);
    });

(See a Demo)

在主线程中的评论之后,似乎初始数据结构(字符串的二维向量)似乎不是最佳选择。

相反,std::mapstd::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 

主要有两点:

  1. 字符串向量不再成为问题,因为在 std::vector<double> 元素的填充中,对字符串调用 std::stod 以将字符串转换为双.

  2. 访问 std::vector<double> 变得微不足道——您需要做的就是获取密钥(字符串数据)并访问(在本例中通过引用),与钥匙。没有复制,没有 std::transform 调用,或类似的东西。