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

Posted

技术标签:

【中文标题】如何将 xarray 转换为 std::vector?【英文标题】:How to convert an xarray to std::vector? 【发布时间】:2020-04-04 15:23:01 【问题描述】:

文档非常清楚地说明了如何使 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 = ?;

【问题讨论】:

【参考方案1】:

您可以从迭代器构造一个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;

参考资料:

std::vector。 Constructors of std::vector(数字 (5) 与此处相关)。 xtensor documentation部分1.7.1 Adapting std::vector

【讨论】:

【参考方案2】:

不幸的是Tom de Geus' answer 不保持维度,因此将xarray of shape 2, 3 转换为vector of size 6。 当我试图构建一个嵌套向量以便用matplotlibcpp 绘制xarray 时,我跳过了这个问题。对我来说,事实证明,Eigen::Matrix.. 是一个更适合这个目的的类。对于二维情况,可以轻松地将 Eigen::Matrix 转换为嵌套的 std::vector。对于更高维度,值得一看here。

代码

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

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



//https://***.com/questions/8443102/convert-eigen-matrix-to-c-array
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;


// https://***.com/a/29243033/7128154
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
// https://***.com/a/31130991/7128154
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]]

【讨论】:

以上是关于如何将 xarray 转换为 std::vector?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义函数应用于 xarray.Dataset 坐标的每个值?

在二维矩阵上使用 std::max_element

如何在 xarray 的后端添加 fsspec.open_local

如何为 xarray 数据数组创建一个 numpy 数组?

如何将 xarray DataArray 与长度为 1 的维度与更大的数组对齐?

数据可视化应用xarray 绘图可视化-创建xarray对象&数据读取和转换&数据索引和分片&插值和广播(附代码)