Eigen3 根据列条件选择行

Nic*_*ela 1 c++ eigen eigen3

我的特征矩阵有一个二维矩阵,例如:

122 443 544 456 0.9
324 435 5465 645 0.8
32 434 545 546 0.778
435 546 6565 656 0.6878
546 6565 656 3453 54 0.7788
5456 546 545 6565 3434 0.244
435 5456 656 656 6565 0.445
.....
Run Code Online (Sandbox Code Playgroud)

当最后一列值大于 0.3 时,我想选择所有行(或获取其行索引)。

我知道我可以通过迭代所有行并判断最后一个元素来做到这一点,但我可能有 10000 行,要做到这一点,迭代会非常慢。

有没有更好的方法来做到这一点?

RHe*_*tel 9

通过将最后一列中所有元素的比较结果存储到一个布尔数组中,可以在一行中完成相关行的选择,该布尔数组可以转换为 VectorXi。

VectorXi is_selected = (mat.col(last_col).array() > 0.3).cast<int>();
Run Code Online (Sandbox Code Playgroud)

然后可以使用该信息来准备仅包含所选行的新矩阵。使用此方法的完整代码如下所示。

#include <Eigen/Dense>
#include <iostream>    
using namespace Eigen;

int main() {
  const int nr = 10;
  const int nc = 5;
  MatrixXd mat = MatrixXd::Random(nr,nc);
  std::cout << "original:\n" << mat << std::endl;
  int last_col = mat.cols() - 1;

  VectorXi is_selected = (mat.col(last_col).array() > 0.3).cast<int>();

  MatrixXd mat_sel(is_selected.sum(), mat.cols());
  int rownew = 0;
  for (int i = 0; i < mat.rows(); ++i) {
    if (is_selected[i]) {       
       mat_sel.row(rownew) = mat.row(i);
       rownew++;
    }
  }
  std::cout << "selected:\n" << mat_sel << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

演示: https: //godbolt.org/z/f0_fC0

编辑:使用新功能(Eigen 3.4 或 3.3.90 开发分支)

Eigen 的开发分支提供了 MatrixX 构造函数的新重载,允许直接对给定矩阵进行子集化。

MatrixXd mat_sel = mat(keep_rows, keep_cols); 
Run Code Online (Sandbox Code Playgroud)

应保留的列和行存储在 aEigen::VectorXi或 a 中std::vector<int>

#include <Eigen/Dense>
#include <iostream>
#include <vector>
using namespace Eigen;

int main() {
  MatrixXd mat = MatrixXd::Random(10,5);
  std::cout << "original:\n" << mat << std::endl;
  std::vector<int> keep_rows;  
  for (int i = 0; i < mat.rows(); ++i) {
    if (mat(i,mat.cols() - 1) > 0.3) {
       keep_rows.push_back(i);
     }     
  }
  VectorXi keep_cols = VectorXi::LinSpaced(mat.cols(), 0, mat.cols());
  MatrixXd mat_sel = mat(keep_rows, keep_cols);          
  std::cout << "selected:\n" << mat_sel << std::endl; 
}
Run Code Online (Sandbox Code Playgroud)

演示: https: //godbolt.org/z/Ag7g7f