1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//! GPU-accelerated quantile operations.
//!
//! Provides quantile computation for [`Column`]s and [`Table`]s.
//!
//! # Examples
//!
//! ```rust,no_run
//! use cudf::Column;
//! use cudf::quantiles::Interpolation;
//!
//! let col = Column::from_slice(&[1.0f64, 2.0, 3.0, 4.0, 5.0]).unwrap();
//! let q = col.quantile(&[0.25, 0.5, 0.75], Interpolation::Linear).unwrap();
//! ```
use crate::column::Column;
use crate::error::{CudfError, Result};
use crate::sorting::{NullOrder, SortOrder};
use crate::table::Table;
/// Interpolation method for quantile computation.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Interpolation {
/// Linear interpolation between data points.
Linear = 0,
/// Use the lower data point.
Lower = 1,
/// Use the higher data point.
Higher = 2,
/// Use the midpoint of the two data points.
Midpoint = 3,
/// Use the nearest data point.
Nearest = 4,
}
impl Column {
/// Compute quantile(s) of this column.
///
/// Returns a column containing one value per requested quantile.
///
/// # Arguments
///
/// * `q` - Slice of quantile values in `[0, 1]`.
/// * `interp` - Interpolation method to use.
///
/// # Errors
///
/// Returns an error if the column type doesn't support quantiles
/// or if a GPU error occurs.
pub fn quantile(&self, q: &[f64], interp: Interpolation) -> Result<Column> {
let raw = cudf_cxx::quantiles::ffi::quantile(&self.inner, q, interp as i32)
.map_err(CudfError::from_cxx)?;
Ok(Column { inner: raw })
}
/// Compute percentile approximation using t-digest.
///
/// This column must contain t-digest data (typically produced by
/// a t-digest aggregation).
///
/// # Arguments
///
/// * `percentiles` - Slice of percentile values in `[0, 1]`.
///
/// # Errors
///
/// Returns an error if the column is not a valid t-digest column
/// or if a GPU error occurs.
pub fn percentile_approx(&self, percentiles: &[f64]) -> Result<Column> {
let raw = cudf_cxx::quantiles::ffi::percentile_approx(&self.inner, percentiles)
.map_err(CudfError::from_cxx)?;
Ok(Column { inner: raw })
}
}
impl Table {
/// Compute quantiles of this table (row-wise).
///
/// Returns a table containing the rows at the requested quantile positions.
///
/// # Arguments
///
/// * `q` - Slice of quantile values in `[0, 1]`.
/// * `interp` - Interpolation method to use.
/// * `is_sorted` - Whether the input is already sorted.
/// * `column_order` - Sort order per column (used if input is sorted).
/// * `null_order` - Null ordering per column (used if input is sorted).
///
/// # Errors
///
/// Returns an error if the arguments are invalid or if a GPU error occurs.
pub fn quantiles(
&self,
q: &[f64],
interp: Interpolation,
is_sorted: bool,
column_order: &[SortOrder],
null_order: &[NullOrder],
) -> Result<Table> {
let orders: Vec<i32> = column_order.iter().map(|o| *o as i32).collect();
let null_orders: Vec<i32> = null_order.iter().map(|o| *o as i32).collect();
let raw = cudf_cxx::quantiles::ffi::quantiles_table(
&self.inner,
q,
interp as i32,
is_sorted,
&orders,
&null_orders,
)
.map_err(CudfError::from_cxx)?;
Ok(Table { inner: raw })
}
}