polars_core/series/ops/
null.rs1use polars_arrow::bitmap::Bitmap;
2use polars_arrow::offset::OffsetsBuffer;
3use polars_buffer::Buffer;
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 {
15 #[cfg(feature = "dtype-map")]
18 dtype
19 .ensure_valid_map_dtypes()
20 .expect("invalid Map dtype in `Series::full_null`");
21
22 match dtype {
24 DataType::List(inner_dtype) => {
25 ListChunked::full_null_with_dtype(name, size, inner_dtype).into_series()
26 },
27 #[cfg(feature = "dtype-array")]
28 DataType::Array(inner_dtype, width) => {
29 ArrayChunked::full_null_with_dtype(name, size, inner_dtype, *width).into_series()
30 },
31 #[cfg(feature = "dtype-categorical")]
32 dt @ (DataType::Categorical(_, _) | DataType::Enum(_, _)) => {
33 with_match_categorical_physical_type!(dt.cat_physical().unwrap(), |$C| {
34 CategoricalChunked::<$C>::full_null_with_dtype(
35 name,
36 size,
37 dtype.clone()
38 )
39 .into_series()
40 })
41 },
42 #[cfg(feature = "dtype-date")]
43 DataType::Date => Int32Chunked::full_null(name, size)
44 .into_date()
45 .into_series(),
46 #[cfg(feature = "dtype-datetime")]
47 DataType::Datetime(tu, tz) => Int64Chunked::full_null(name, size)
48 .into_datetime(*tu, tz.clone())
49 .into_series(),
50 #[cfg(feature = "dtype-duration")]
51 DataType::Duration(tu) => Int64Chunked::full_null(name, size)
52 .into_duration(*tu)
53 .into_series(),
54 #[cfg(feature = "dtype-time")]
55 DataType::Time => Int64Chunked::full_null(name, size)
56 .into_time()
57 .into_series(),
58 #[cfg(feature = "dtype-decimal")]
59 DataType::Decimal(precision, scale) => Int128Chunked::full_null(name, size)
60 .into_decimal_unchecked(*precision, *scale)
61 .into_series(),
62 #[cfg(feature = "dtype-struct")]
63 DataType::Struct(fields) => {
64 let fields = fields
65 .iter()
66 .map(|fld| Series::full_null(fld.name().clone(), size, fld.dtype()))
67 .collect::<Vec<_>>();
68 let ca = StructChunked::from_series(name, size, fields.iter()).unwrap();
69
70 ca.with_outer_validity(Some(Bitmap::new_zeroed(size)))
71 .into_series()
72 },
73 DataType::BinaryOffset => {
74 let length = size;
75
76 let offsets = vec![0; size + 1];
77 let array = BinaryArray::<i64>::new(
78 dtype.to_arrow(CompatLevel::oldest()),
79 unsafe { OffsetsBuffer::new_unchecked(Buffer::from(offsets)) },
80 Buffer::default(),
81 Some(Bitmap::new_zeroed(size)),
82 );
83
84 unsafe {
85 BinaryOffsetChunked::new_with_dims(
86 Arc::new(Field::new(name, dtype.clone())),
87 vec![Box::new(array)],
88 length,
89 length,
90 )
91 }
92 .into_series()
93 },
94 DataType::Null => Series::new_null(name, size),
95 DataType::Unknown(kind) => {
96 let dtype = kind.materialize().unwrap_or(DataType::Null);
97 Series::full_null(name, size, &dtype)
98 },
99 #[cfg(feature = "object")]
100 DataType::Object(_) => {
101 let mut builder = get_object_builder(name, size);
102 for _ in 0..size {
103 builder.append_null();
104 }
105 builder.to_series()
106 },
107 #[cfg(feature = "dtype-map")]
108 DataType::Map(_, _) => {
109 let storage = Series::full_null(name, size, &dtype.map_storage_dtype().unwrap());
110 unsafe { MapChunked::from_storage_unchecked(dtype.clone(), storage) }.into_series()
112 },
113 #[cfg(feature = "dtype-extension")]
114 DataType::Extension(typ, storage_dtype) => {
115 Series::full_null(name, size, storage_dtype).into_extension(typ.clone())
116 },
117 _ => {
118 macro_rules! primitive {
119 ($type:ty) => {{ ChunkedArray::<$type>::full_null(name, size).into_series() }};
120 }
121 macro_rules! bool {
122 () => {{ ChunkedArray::<BooleanType>::full_null(name, size).into_series() }};
123 }
124 macro_rules! string {
125 () => {{ ChunkedArray::<StringType>::full_null(name, size).into_series() }};
126 }
127 macro_rules! binary {
128 () => {{ ChunkedArray::<BinaryType>::full_null(name, size).into_series() }};
129 }
130 match_dtype_to_logical_apply_macro!(dtype, primitive, string, binary, bool)
131 },
132 }
133 }
134}