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
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use super::*;
use crate::{map, map_owned};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, PartialEq, Debug, Eq, Hash)]
pub enum NanFunction {
IsNan,
IsNotNan,
DropNans,
}
pub(super) fn is_nan(s: &Series) -> PolarsResult<Series> {
s.is_nan().map(|ca| ca.into_series())
}
pub(super) fn is_not_nan(s: &Series) -> PolarsResult<Series> {
s.is_not_nan().map(|ca| ca.into_series())
}
pub(super) fn drop_nans(s: Series) -> PolarsResult<Series> {
match s.dtype() {
DataType::Float32 => {
let ca = s.f32()?;
let mask = ca.is_not_nan();
ca.filter(&mask).map(|ca| ca.into_series())
}
DataType::Float64 => {
let ca = s.f64()?;
let mask = ca.is_not_nan();
ca.filter(&mask).map(|ca| ca.into_series())
}
_ => Ok(s),
}
}
impl NanFunction {
pub(crate) fn get_field(&self, fields: &[Field]) -> PolarsResult<Field> {
let with_dtype = |dtype: DataType| Ok(Field::new(fields[0].name(), dtype));
let map_dtype = |func: &dyn Fn(&DataType) -> DataType| {
let dtype = func(fields[0].data_type());
Ok(Field::new(fields[0].name(), dtype))
};
let same_type = || map_dtype(&|dtype| dtype.clone());
match self {
NanFunction::IsNan => with_dtype(DataType::Boolean),
NanFunction::IsNotNan => with_dtype(DataType::Boolean),
NanFunction::DropNans => same_type(),
}
}
}
impl From<NanFunction> for SpecialEq<Arc<dyn SeriesUdf>> {
fn from(nan_function: NanFunction) -> Self {
match nan_function {
NanFunction::IsNan => map!(is_nan),
NanFunction::IsNotNan => map!(is_not_nan),
NanFunction::DropNans => map_owned!(drop_nans),
}
}
}
impl From<NanFunction> for FunctionExpr {
fn from(nan_function: NanFunction) -> Self {
FunctionExpr::Nan(nan_function)
}
}