【问题标题】:How to convert an xarray to std::vector?如何将 xarray 转换为 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 = ?;

【问题讨论】:

    标签: stdvector xtensor


    【解决方案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;
    }
    

    参考资料:

    【讨论】:

      【解决方案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::MatrixXf 为nested std::vector

      #include "xtensor/xarray.hpp"
      #include "xtensor/xio.hpp"
      #include <Eigen/Dense>
      
      
      
      //https://stackoverflow.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://stackoverflow.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://stackoverflow.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]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-03-31
        • 2016-12-06
        • 2021-03-02
        • 2018-05-25
        • 2020-12-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多