Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-expr/src/dispatch/struct_.rs
8412 views
1
use std::sync::Arc;
2
3
use polars_core::error::{PolarsResult, polars_err};
4
use polars_core::prelude::{
5
Column, InitHashMaps, IntoColumn, PlIndexMap, StringChunked, StructChunked,
6
};
7
use polars_plan::dsl::{ColumnsUdf, SpecialEq};
8
use polars_plan::plans::IRStructFunction;
9
use polars_plan::prelude::PlanCallback;
10
use polars_utils::format_pl_smallstr;
11
use polars_utils::pl_str::PlSmallStr;
12
13
pub fn function_expr_to_udf(func: IRStructFunction) -> SpecialEq<Arc<dyn ColumnsUdf>> {
14
use IRStructFunction::*;
15
match func {
16
FieldByName(name) => map!(get_by_name, &name),
17
RenameFields(names) => map!(rename_fields, names.clone()),
18
PrefixFields(prefix) => map!(prefix_fields, prefix.as_str()),
19
SuffixFields(suffix) => map!(suffix_fields, suffix.as_str()),
20
#[cfg(feature = "json")]
21
JsonEncode => map!(to_json),
22
MapFieldNames(function) => map!(map_field_names, &function),
23
}
24
}
25
26
pub(super) fn get_by_name(s: &Column, name: &str) -> PolarsResult<Column> {
27
let ca = s.struct_()?;
28
ca.field_by_name(name).map(Column::from)
29
}
30
31
pub(super) fn rename_fields(s: &Column, names: Arc<[PlSmallStr]>) -> PolarsResult<Column> {
32
let ca = s.struct_()?;
33
let fields = ca
34
.fields_as_series()
35
.iter()
36
.zip(names.as_ref())
37
.map(|(s, name)| {
38
let mut s = s.clone();
39
s.rename(name.clone());
40
s
41
})
42
.collect::<Vec<_>>();
43
let mut out = StructChunked::from_series(ca.name().clone(), ca.len(), fields.iter())?;
44
out.zip_outer_validity(ca);
45
Ok(out.into_column())
46
}
47
48
pub(super) fn prefix_fields(s: &Column, prefix: &str) -> PolarsResult<Column> {
49
let ca = s.struct_()?;
50
let fields = ca
51
.fields_as_series()
52
.iter()
53
.map(|s| {
54
let mut s = s.clone();
55
let name = s.name();
56
s.rename(format_pl_smallstr!("{prefix}{name}"));
57
s
58
})
59
.collect::<Vec<_>>();
60
let mut out = StructChunked::from_series(ca.name().clone(), ca.len(), fields.iter())?;
61
out.zip_outer_validity(ca);
62
Ok(out.into_column())
63
}
64
65
pub(super) fn suffix_fields(s: &Column, suffix: &str) -> PolarsResult<Column> {
66
let ca = s.struct_()?;
67
let fields = ca
68
.fields_as_series()
69
.iter()
70
.map(|s| {
71
let mut s = s.clone();
72
let name = s.name();
73
s.rename(format_pl_smallstr!("{name}{suffix}"));
74
s
75
})
76
.collect::<Vec<_>>();
77
let mut out = StructChunked::from_series(ca.name().clone(), ca.len(), fields.iter())?;
78
out.zip_outer_validity(ca);
79
Ok(out.into_column())
80
}
81
82
#[cfg(feature = "json")]
83
pub(super) fn to_json(col: &Column) -> PolarsResult<Column> {
84
use polars_core::prelude::CompatLevel;
85
86
let s = col.as_materialized_series();
87
let iter = (0..s.n_chunks()).map(|i| {
88
polars_json::json::write::serialize_to_utf8(&*s.to_arrow(i, CompatLevel::newest()))
89
});
90
91
Ok(StringChunked::from_chunk_iter(s.name().clone(), iter).into_column())
92
}
93
94
pub(crate) fn with_fields(args: &[Column]) -> PolarsResult<Column> {
95
let s = &args[0];
96
97
let ca = s.struct_()?;
98
let current = ca.fields_as_series();
99
100
let mut fields = PlIndexMap::with_capacity(current.len() + s.len() - 1);
101
102
for field in current.iter() {
103
fields.insert(field.name(), field);
104
}
105
106
for field in &args[1..] {
107
fields.insert(field.name(), field.as_materialized_series());
108
}
109
110
let new_fields = fields.into_values().cloned().collect::<Vec<_>>();
111
let mut out = StructChunked::from_series(ca.name().clone(), ca.len(), new_fields.iter())?;
112
out.zip_outer_validity(ca);
113
Ok(out.into_column())
114
}
115
116
pub(super) fn map_field_names(
117
s: &Column,
118
function: &PlanCallback<PlSmallStr, PlSmallStr>,
119
) -> PolarsResult<Column> {
120
let ca = s.struct_()?;
121
let fields = ca
122
.fields_as_series()
123
.iter()
124
.map(|s| {
125
let mut s = s.clone();
126
let name = s.name();
127
let new_name = function.call(name.clone()).map_err(
128
|e| polars_err!(ComputeError: "'name.map_fields' produced an error: {e}."),
129
)?;
130
s.rename(new_name);
131
Ok(s)
132
})
133
.collect::<PolarsResult<Vec<_>>>()?;
134
let mut out = StructChunked::from_series(ca.name().clone(), ca.len(), fields.iter())?;
135
out.zip_outer_validity(ca);
136
Ok(out.into_column())
137
}
138
139