polars_core/chunked_array/ops/
decimal.rs1use crate::chunked_array::cast::CastOptions;
2use crate::prelude::*;
3
4impl StringChunked {
5 pub fn to_decimal_infer(&self, infer_length: usize) -> PolarsResult<Series> {
13 let mut scale = 0;
14 let mut iter = self.into_iter();
15 let mut valid_count = 0;
16 while let Some(Some(v)) = iter.next() {
17 let scale_value = arrow::compute::decimal::infer_scale(v.as_bytes());
18 scale = std::cmp::max(scale, scale_value);
19 valid_count += 1;
20 if valid_count == infer_length {
21 break;
22 }
23 }
24
25 self.to_decimal(scale as usize)
26 }
27
28 pub fn to_decimal(&self, scale: usize) -> PolarsResult<Series> {
29 self.cast_with_options(
30 &DataType::Decimal(None, Some(scale)),
31 CastOptions::NonStrict,
32 )
33 }
34}
35
36#[cfg(test)]
37mod test {
38 #[test]
39 fn test_inferred_length() {
40 use super::*;
41 let vals = [
42 "1.0",
43 "invalid",
44 "225.0",
45 "3.00045",
46 "-4.0",
47 "5.104",
48 "5.25251525353",
49 ];
50 let s = StringChunked::from_slice(PlSmallStr::from_str("test"), &vals);
51 let s = s.to_decimal_infer(6).unwrap();
52 assert_eq!(s.dtype(), &DataType::Decimal(None, Some(5)));
53 assert_eq!(s.len(), 7);
54 assert_eq!(s.get(0).unwrap(), AnyValue::Decimal(100000, 5));
55 assert_eq!(s.get(1).unwrap(), AnyValue::Null);
56 assert_eq!(s.get(3).unwrap(), AnyValue::Decimal(300045, 5));
57 assert_eq!(s.get(4).unwrap(), AnyValue::Decimal(-400000, 5));
58 assert_eq!(s.get(6).unwrap(), AnyValue::Decimal(525251, 5));
59 }
60}