我在本征中有一个二维的矩阵,例如:
<ip 1> - - [11/Oct/2019:12:00:24 -0600] "POST /xml_parse/ HTTP/1.1" 406 226 "-" "-" www.certainplace.com <ip 2>
当最后一列的值大于0.3时,我想选择所有行(或获取其行索引)。
我知道我可以通过迭代所有行并判断最后一个元素来执行此操作,但是我可能有10000行,要执行此操作,迭代将非常慢。
还有更好的方法吗?
答案 0 :(得分:1)
您可以尝试使用列而不是行,并将最后一列与矢量[n x 1]的0.3比较
答案 1 :(得分:1)
通过将最后一列中所有元素的比较结果存储到一个布尔数组中,可以在一行中完成相关行的选择,该布尔数组可以转换为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;
}
演示: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;
}