如何将一个犰狳矩阵转换为立方体?

2024-10-01 09:19:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试重新创建以下Python numpy代码:

num_rows, num_cols = data.shape
N = 4
data = data.reshape(N, num_rows/N, num_cols)
C++中使用ARMADILO矩阵和立方体< P>如何才能最有效地做到这一点。我不认为调整大小/重塑操作直接支持从二维矩阵移动到三维立方体?在


Tags: 代码numpydata矩阵numrowscolsshape
2条回答

构造这样一个立方体最快的方法是使用advanced constructors中的一个。这些允许您直接从内存的任意部分创建一个新对象,即使不复制任何数据。这在精神上最接近NumPy的重塑方式,即返回原始数据的视图,而不是副本。在

你可以这样使用构造函数:

// Assuming a is an arma::mat.
int N = 4;
arma::cube c(a.memptr(), N, a.n_rows / N, a.n_cols, false);

它直接从a获取内存,而不进行复制,并将其用作c的数据。在

当然,这很快,但很危险。您负责保证只要c存在,指向的内存就有效。这意味着c的生存期必须严格嵌套在a的生存期中。这很难保证,尤其是当a和{}都在堆上创建时。在

您还可以通过省略最后一个参数或将其设置为true,允许c复制a的数据。这比不复制构造函数花费更多的时间,但可能比从a的数据分配每个片段要少,因为这个构造函数只对底层数据进行一个大容量的memcpy。在

所有这些都取决于@ewcz的答案所提出的行与列的主要观点。确保你知道你在重塑时得到了什么,尤其是当你使用高级构造函数的时候。在

由于armadillo使用数据的列主排序(与numpy不同,numpy依赖于行主序),所以简单地将矩阵放入一个具有1个切片的立方体中并对其进行整形将产生不同的结果(下面的矩阵B)。另一种方法是手动构造切片:

#include <iostream>
#include <armadillo>

int main(){

    const arma::uword N = 2;
    const arma::uword num_rows = 4;
    const arma::uword num_cols = 3;

    arma::mat A(num_rows, num_cols, arma::fill::randu);

    std::cout << A;

    arma::cube B(num_rows, num_cols, 1);
    B.slice(0) = A;
    B.reshape(num_rows/N, num_cols, N);
    std::cout << B;

    arma::cube C(num_rows/N, num_cols, N);
    for(arma::uword i = 0; i < N; ++i){
        C.slice(i) = A.rows(i*N, (i+1)*N-1);
    }
    std::cout << C;


    return 0;
}

相关问题 更多 >