如何将 xarray 转换为 std::vector?

How to convert an xarray to std::vector?

文档非常清楚如何使 std::vector 适应张量对象。 https://xtensor.readthedocs.io/en/latest/adaptor.html

std::vector<double> v = {1., 2., 3., 4., 5., 6. };
std::vector<std::size_t> shape = { 2, 3 };
auto a1 = xt::adapt(v, shape);

但是你怎么能反过来呢?

xt::xarray<double> a2 = { { 1., 2., 3.} };
std::vector<double> a2vector = ?;

您可以从迭代器构造一个 std::vector。例如:

std::vector<double> w(a1.begin(), a1.end());

完整的例子就变成了:

#include <vector>
#include <xtensor/xadapt.hpp>
#include <xtensor/xio.hpp>

int main()
{
    std::vector<double> v = {1., 2., 3., 4., 5., 6.};
    std::vector<std::size_t> shape = {2, 3};
    auto a1 = xt::adapt(v, shape);
    std::vector<double> w(a1.begin(), a1.end());
    return 0;
}

参考文献:

不幸的是 不保持维度,因此将 xarray of shape {2, 3} 转换为 vector of size 6。 当我试图构造一个嵌套向量以便用 matplotlibcpp 绘制 xarray 时,我跳过了这个问题。结果对我来说,Eigen::Matrix.. is a way more suitable class for this purpose. For the 2 dimensional case, one can comfortable convert the Eigen::Matrix to a nested std::vector. For higher dimensions, its worth to have a look .

代码

xt::xarray 转换为 Eigen::MatrixXfnested std::vector

#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
#include <Eigen/Dense>



//
Eigen::MatrixXf xarray_to_matrixXf(xt::xarray<float> arr)
{
      auto shape = arr.shape();
      int nrows = shape[0];
      int ncols = shape[1];

      Eigen::MatrixXf mat = Eigen::Map<Eigen::MatrixXf>(arr.data(), nrows, ncols);
      return mat;
}

// 
std::vector<std::vector<float>> matrixXf2d_to_vector(Eigen::MatrixXf mat)
{
      std::vector<std::vector<float>> vec;

      for (int i=0; i<mat.rows(); ++i)
      {
          const float* begin = &mat.row(i).data()[0];
          vec.push_back(std::vector<float>(begin, begin+mat.cols()));
      }
      return vec;
}

// print a vector
// 
template<typename T1>
std::ostream& operator <<( std::ostream& out, const std::vector<T1>& object )
{
      out << "[";
      if ( !object.empty() )
      {
          for(typename std::vector<T1>::const_iterator
              iter = object.begin();
              iter != --object.end();
              ++iter) {
                  out << *iter << ", ";
          }
          out << *--object.end();
      }
      out << "]";
      return out;
}


int main()
{
      xt::xarray<float> xArr {{nan(""), 9}, {5, -6}, {1, 77}};
      std::cout << "xt::xarray<float> xArr = \n" << xArr << std::endl;


      Eigen::MatrixXf eigMat = xarray_to_matrixXf(xArr);
      std::cout << "Eigen::MatrixXf eigMat = \n" << eigMat << std::endl;

      std::vector<std::vector<float>> vec = matrixXf2d_to_vector(eigMat);
      std::cout << "std::vector<std::vector<float>> vec = " << vec << std::endl;

      return 0;
}

输出

xt::xarray<float> xArr = 
{{nan.,   9.},
 {  5.,  -6.},
 {  1.,  77.}}
Eigen::MatrixXf eigMat = 
nan  -6
  9   1
  5  77
std::vector<std::vector<float>> vec = [[nan, 9], [9, 5], [5, -6]]