pub use numpy::{PyArray1, PyArray2, PyReadonlyArray2};
pub use pyo3::exceptions::PyValueError;
pub use pyo3::prelude::*;
pub use scirs2_core::ndarray::{Array1, Array2};
#[cfg(feature = "parallel")]
pub use rayon::prelude::*;
pub type PreprocessingResult<T> = Result<T, PyValueError>;
pub fn validate_fit_array(x: &Array2<f64>) -> PyResult<()> {
if x.nrows() == 0 {
return Err(PyValueError::new_err("Input array must not be empty"));
}
if x.ncols() == 0 {
return Err(PyValueError::new_err(
"Input array must have at least one feature",
));
}
if !x.iter().all(|&val| val.is_finite()) {
return Err(PyValueError::new_err(
"Input array contains non-finite values",
));
}
Ok(())
}
pub fn validate_transform_array(x: &Array2<f64>, expected_features: usize) -> PyResult<()> {
if x.nrows() == 0 {
return Err(PyValueError::new_err("Input array must not be empty"));
}
if x.ncols() == 0 {
return Err(PyValueError::new_err(
"Input array must have at least one feature",
));
}
if x.ncols() != expected_features {
return Err(PyValueError::new_err(format!(
"Input has {} features, but transformer was fitted with {} features",
x.ncols(),
expected_features
)));
}
if !x.iter().all(|&val| val.is_finite()) {
return Err(PyValueError::new_err(
"Input array contains non-finite values",
));
}
Ok(())
}
pub fn pyarray_to_core_array2(py_array: &PyReadonlyArray2<f64>) -> PyResult<Array2<f64>> {
let array_view = py_array.as_array();
let shape = array_view.shape();
if shape.len() != 2 {
return Err(PyValueError::new_err("Expected a 2D array"));
}
let rows = shape[0];
let cols = shape[1];
Array2::from_shape_vec((rows, cols), array_view.iter().cloned().collect())
.map_err(|_| PyValueError::new_err("Failed to convert NumPy array to ndarray"))
}
pub fn core_array1_to_py<'py>(py: Python<'py>, array: &Array1<f64>) -> Py<PyArray1<f64>> {
let numpy_array = numpy::ndarray::Array1::from_vec(array.to_vec());
PyArray1::from_owned_array(py, numpy_array).into()
}
pub fn core_array2_to_py<'py>(py: Python<'py>, array: &Array2<f64>) -> PyResult<Py<PyArray2<f64>>> {
let (rows, cols) = array.dim();
let data: Vec<f64> = array.iter().cloned().collect();
let numpy_array = numpy::ndarray::Array2::from_shape_vec((rows, cols), data)
.map_err(|_| PyValueError::new_err("Failed to convert ndarray to NumPy array"))?;
Ok(PyArray2::from_owned_array(py, numpy_array).into())
}