is there way to delete a column or extract a sub matrix from Smartcore dense matrix?

Viewed 112

I'm working with the smartcore library in rust. Trying to delete the last column from a DenseMatrix. I thought maybe of creating an identity matrix with the right columns and rows. but didn't really figure out how to do that.

use smartcore::linalg::naive::dense_matrix::DenseMatrix;
use smartcore::linalg::BaseMatrix;

fn main(){
   let rows = 20
   let cols = 20
   let id_matrix = DenseMatrix::ones(rows, cols-1); //??
}
1 Answers

You could do something like this to remove some items (rows as well as columns) from an array and create DenseMatrix after.

// DenseMatrix defenition
use smartcore::linalg::naive::dense_matrix::*;
// KNNClassifier
use smartcore::neighbors::knn_classifier::*;

fn main() {
    // Turn Rust vectors with samples into a matrix
    let arr = [[1., 2.], [3., 4.], [5., 6.], [7., 8.], [9., 10.]];
    let arr_slice: Vec<&[_]> = arr
        .iter()
        .enumerate()
        .filter(|&(i, _)| i < 4) // Take into account rows 0 to 3
        .inspect(|x| println!("item {:?}", x)) // comment after debugging
        .map(|(_,v)| v.as_ref())
        .collect();
    let x = DenseMatrix::from_2d_array(&arr_slice);
    let y = vec![2., 2., 2., 3.];

    // Train classifier
    let knn = KNNClassifier::fit(&x, &y, Default::default()).unwrap();

    // Predict classes
    let result = knn.predict(&x).unwrap();
    println!("{:?}", result);
}

As a result you will get:

item (0, [1.0, 2.0])
item (1, [3.0, 4.0])
item (2, [5.0, 6.0])
item (3, [7.0, 8.0])
[2.0, 2.0, 2.0, 2.0]

The idea is to transform an array [[_]] into slice &[&[_]]. Thanks to the enumerator I can get the index of the row, so I just have to filter through it. The inspector method can be commented at the end when you are satisfied with the result.

Now that you need to remove last column, you can take a slice [..2] on each row as shown :

fn main() {
    // Turn Rust vectors with samples into a matrix
    let arr = [[1., 2., 9.], [3., 4., 9.], [5., 6., 9.], [7., 8., 9.], [9., 10., 9.]];
    let arr_slice: Vec<&[_]> = arr
        .iter()
        .enumerate()
        .filter(|&(i, _)| i < 4) // Take into account rows 0 to 3
        .inspect(|x| println!("item {:?}", x)) // comment after debugging
        .map(|(_,v)| v[..2].as_ref()) // take into account columns 0 to 1
        .inspect(|x| println!("item now {:?}", x)) // comment after debugging
        .collect();
    let x = DenseMatrix::from_2d_array(&arr_slice);
    let y = vec![2., 2., 2., 3.];

    // Train classifier
    let knn = KNNClassifier::fit(&x, &y, Default::default()).unwrap();

    // Predict classes
    println!("{:?}", knn.predict(&x).unwrap());
}

And the result is:

item (0, [1.0, 2.0, 9.0])
item now [1.0, 2.0]
item (1, [3.0, 4.0, 9.0])
item now [3.0, 4.0]
item (2, [5.0, 6.0, 9.0])
item now [5.0, 6.0]
item (3, [7.0, 8.0, 9.0])
item now [7.0, 8.0]
[2.0, 2.0, 2.0, 2.0]
Related