scouter_client/data_utils/
base.rs

1use crate::data_utils::{ConvertedData, DataTypes};
2
3use crate::error::DataError;
4use num_traits::Float;
5use numpy::PyArray2;
6use numpy::PyArrayMethods;
7use numpy::PyReadonlyArray2;
8use pyo3::prelude::*;
9
10pub fn convert_array_type<'py, F>(
11    data: Bound<'py, PyAny>,
12    dtype: &str,
13) -> Result<PyReadonlyArray2<'py, F>, DataError>
14where
15    F: Float + numpy::Element,
16{
17    let array = if dtype.contains("int") {
18        data.call_method1("astype", ("float32",))?
19    } else {
20        data.clone()
21    };
22
23    let array = array
24        .downcast_into::<PyArray2<F>>()
25        .map_err(|e| DataError::DowncastError(e.to_string()))?;
26
27    Ok(array.readonly())
28}
29
30pub trait DataConverter {
31    fn categorize_features<'py>(
32        py: Python<'py>,
33        data: &Bound<'py, PyAny>,
34    ) -> Result<DataTypes, DataError>;
35
36    #[allow(clippy::needless_lifetimes)]
37    fn process_numeric_features<'py>(
38        data: &Bound<'py, PyAny>,
39        data_type: &DataTypes,
40    ) -> Result<(Option<Bound<'py, PyAny>>, Option<String>), DataError>;
41
42    #[allow(clippy::needless_lifetimes)]
43    fn process_string_features<'py>(
44        data: &Bound<'py, PyAny>,
45        features: &[String],
46    ) -> Result<Option<Vec<Vec<String>>>, DataError>;
47
48    fn prepare_data<'py>(
49        py: Python<'py>,
50        data: &Bound<'py, PyAny>,
51    ) -> Result<ConvertedData<'py>, DataError>;
52}