polars_core/series/ops/
null.rs

1use arrow::bitmap::Bitmap;
2use arrow::buffer::Buffer;
3use arrow::offset::OffsetsBuffer;
4
5#[cfg(feature = "object")]
6use crate::chunked_array::object::registry::get_object_builder;
7use crate::prelude::*;
8
9impl Series {
10    pub fn full_null(name: PlSmallStr, size: usize, dtype: &DataType) -> Self {
11        // match the logical types and create them
12        match dtype {
13            DataType::List(inner_dtype) => {
14                ListChunked::full_null_with_dtype(name, size, inner_dtype).into_series()
15            },
16            #[cfg(feature = "dtype-array")]
17            DataType::Array(inner_dtype, width) => {
18                ArrayChunked::full_null_with_dtype(name, size, inner_dtype, *width).into_series()
19            },
20            #[cfg(feature = "dtype-categorical")]
21            dt @ (DataType::Categorical(rev_map, ord) | DataType::Enum(rev_map, ord)) => {
22                let mut ca = CategoricalChunked::full_null(
23                    name,
24                    matches!(dt, DataType::Enum(_, _)),
25                    size,
26                    *ord,
27                );
28                // ensure we keep the rev-map of a cleared series
29                if let Some(rev_map) = rev_map {
30                    unsafe { ca.set_rev_map(rev_map.clone(), false) }
31                }
32                ca.into_series()
33            },
34            #[cfg(feature = "dtype-date")]
35            DataType::Date => Int32Chunked::full_null(name, size)
36                .into_date()
37                .into_series(),
38            #[cfg(feature = "dtype-datetime")]
39            DataType::Datetime(tu, tz) => Int64Chunked::full_null(name, size)
40                .into_datetime(*tu, tz.clone())
41                .into_series(),
42            #[cfg(feature = "dtype-duration")]
43            DataType::Duration(tu) => Int64Chunked::full_null(name, size)
44                .into_duration(*tu)
45                .into_series(),
46            #[cfg(feature = "dtype-time")]
47            DataType::Time => Int64Chunked::full_null(name, size)
48                .into_time()
49                .into_series(),
50            #[cfg(feature = "dtype-decimal")]
51            DataType::Decimal(precision, scale) => Int128Chunked::full_null(name, size)
52                .into_decimal_unchecked(*precision, scale.unwrap_or(0))
53                .into_series(),
54            #[cfg(feature = "dtype-struct")]
55            DataType::Struct(fields) => {
56                let fields = fields
57                    .iter()
58                    .map(|fld| Series::full_null(fld.name().clone(), size, fld.dtype()))
59                    .collect::<Vec<_>>();
60                let ca = StructChunked::from_series(name, size, fields.iter()).unwrap();
61
62                if !fields.is_empty() {
63                    ca.with_outer_validity(Some(Bitmap::new_zeroed(size)))
64                        .into_series()
65                } else {
66                    ca.into_series()
67                }
68            },
69            DataType::BinaryOffset => {
70                let length = size;
71
72                let offsets = vec![0; size + 1];
73                let array = BinaryArray::<i64>::new(
74                    dtype.to_arrow(CompatLevel::oldest()),
75                    unsafe { OffsetsBuffer::new_unchecked(Buffer::from(offsets)) },
76                    Buffer::default(),
77                    Some(Bitmap::new_zeroed(size)),
78                );
79
80                unsafe {
81                    BinaryOffsetChunked::new_with_dims(
82                        Arc::new(Field::new(name, dtype.clone())),
83                        vec![Box::new(array)],
84                        length,
85                        length,
86                    )
87                }
88                .into_series()
89            },
90            DataType::Null => Series::new_null(name, size),
91            DataType::Unknown(kind) => {
92                let dtype = kind.materialize().unwrap_or(DataType::Null);
93                Series::full_null(name, size, &dtype)
94            },
95            #[cfg(feature = "object")]
96            DataType::Object(_) => {
97                let mut builder = get_object_builder(name, size);
98                for _ in 0..size {
99                    builder.append_null();
100                }
101                builder.to_series()
102            },
103            _ => {
104                macro_rules! primitive {
105                    ($type:ty) => {{ ChunkedArray::<$type>::full_null(name, size).into_series() }};
106                }
107                macro_rules! bool {
108                    () => {{ ChunkedArray::<BooleanType>::full_null(name, size).into_series() }};
109                }
110                macro_rules! string {
111                    () => {{ ChunkedArray::<StringType>::full_null(name, size).into_series() }};
112                }
113                macro_rules! binary {
114                    () => {{ ChunkedArray::<BinaryType>::full_null(name, size).into_series() }};
115                }
116                match_dtype_to_logical_apply_macro!(dtype, primitive, string, binary, bool)
117            },
118        }
119    }
120}