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
use crate::chunked_array::kernels::{is_finite, is_infinite, is_nan, is_not_nan}; use crate::{ prelude::*, utils::{integer_decode_f32, integer_decode_f64}, }; use num::Float; pub trait ChunkIntegerDecode { fn integer_decode(&self) -> (UInt64Chunked, Int16Chunked, Int8Chunked); } pub trait IntegerDecode { fn integer_decode(&self) -> (u64, i16, i8); } impl IntegerDecode for f64 { fn integer_decode(&self) -> (u64, i16, i8) { integer_decode_f64(*self) } } impl IntegerDecode for f32 { fn integer_decode(&self) -> (u64, i16, i8) { integer_decode_f32(*self) } } fn process_float<T>( val: T, u64_builder: &mut PrimitiveChunkedBuilder<UInt64Type>, i16_builder: &mut PrimitiveChunkedBuilder<Int16Type>, i8_builder: &mut PrimitiveChunkedBuilder<Int8Type>, ) where T: IntegerDecode, { let (mantissa, exponent, sign) = val.integer_decode(); u64_builder.append_value(mantissa); i16_builder.append_value(exponent); i8_builder.append_value(sign); } impl<T> ChunkIntegerDecode for ChunkedArray<T> where T: PolarsNumericType, T::Native: IntegerDecode, { fn integer_decode(&self) -> (UInt64Chunked, Int16Chunked, Int8Chunked) { let name = self.name(); let name_len = name.len(); let mut u64_name = String::with_capacity(name_len + 3); u64_name.push_str(name); u64_name.push_str("u64"); let mut i16_name = String::with_capacity(name_len + 3); i16_name.push_str(name); i16_name.push_str("i16"); let mut i8_name = String::with_capacity(name_len + 3); i8_name.push_str(name); i8_name.push_str("i16"); let mut u64_builder = PrimitiveChunkedBuilder::<UInt64Type>::new(&u64_name, self.len()); let mut i16_builder = PrimitiveChunkedBuilder::<Int16Type>::new(&i16_name, self.len()); let mut i8_builder = PrimitiveChunkedBuilder::<Int8Type>::new(&i8_name, self.len()); match self.null_count() { 0 => self.into_no_null_iter().for_each(|v| { process_float(v, &mut u64_builder, &mut i16_builder, &mut i8_builder) }), _ => self.into_iter().for_each(|opt_v| { if let Some(v) = opt_v { process_float(v, &mut u64_builder, &mut i16_builder, &mut i8_builder) } }), } ( u64_builder.finish(), i16_builder.finish(), i8_builder.finish(), ) } } pub trait IsNan { fn is_nan(&self) -> BooleanChunked; fn is_not_nan(&self) -> BooleanChunked; fn is_finite(&self) -> BooleanChunked; fn is_infinite(&self) -> BooleanChunked; } impl<T> IsNan for ChunkedArray<T> where T: PolarsFloatType, T::Native: Float, { fn is_nan(&self) -> BooleanChunked { self.apply_kernel_cast(is_nan) } fn is_not_nan(&self) -> BooleanChunked { self.apply_kernel_cast(is_not_nan) } fn is_finite(&self) -> BooleanChunked { self.apply_kernel_cast(is_finite) } fn is_infinite(&self) -> BooleanChunked { self.apply_kernel_cast(is_infinite) } }