通过将最后一列中所有元素的比较结果存储到一个布尔数组中,可以在一行中完成相关行的选择,该布尔数组可以转换为 VectorXi。
VectorXi is_selected = (mat.col(last_col).array() > 0.3).cast<int>();
然后可以使用该信息来准备一个仅包含所选行的新矩阵。使用此方法的完整代码如下所示。
#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;
}
Demo: https://godbolt.org/z/f0_fC0
编辑:使用新功能(Eigen 3.4 或 3.3.90 开发分支)
Eigen 的开发分支提供了 MatrixX 构造函数的新重载,允许直接对给定矩阵进行子集化。
MatrixXd mat_sel = mat(keep_rows, keep_cols);
应保留的列和行存储在Eigen::VectorXi
或在一个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;
}
Demo: https://godbolt.org/z/Ag7g7f