Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-time/src/replace.rs
6939 views
1
use polars_core::prelude::*;
2
3
use crate::prelude::*;
4
5
/// Replace specific time component of a `DatetimeChunked` with a specified value.
6
#[cfg(feature = "dtype-datetime")]
7
#[allow(clippy::too_many_arguments)]
8
pub fn replace_datetime(
9
ca: &DatetimeChunked,
10
year: &Int32Chunked,
11
month: &Int8Chunked,
12
day: &Int8Chunked,
13
hour: &Int8Chunked,
14
minute: &Int8Chunked,
15
second: &Int8Chunked,
16
nanosecond: &Int32Chunked,
17
ambiguous: &StringChunked,
18
) -> PolarsResult<DatetimeChunked> {
19
let n = [
20
ca.len(),
21
year.len(),
22
month.len(),
23
day.len(),
24
hour.len(),
25
minute.len(),
26
second.len(),
27
nanosecond.len(),
28
ambiguous.len(),
29
]
30
.into_iter()
31
.find(|l| *l != 1)
32
.unwrap_or(1);
33
34
for (i, (name, length)) in [
35
("self", ca.len()),
36
("year", year.len()),
37
("month", month.len()),
38
("day", day.len()),
39
("hour", hour.len()),
40
("minute", minute.len()),
41
("second", second.len()),
42
("nanosecond", nanosecond.len()),
43
("ambiguous", ambiguous.len()),
44
]
45
.into_iter()
46
.enumerate()
47
{
48
polars_ensure!(
49
length == n || length == 1,
50
length_mismatch = "dt.replace",
51
length,
52
n,
53
argument = name,
54
argument_idx = i
55
);
56
}
57
58
// For each argument, we must check if:
59
// 1. No value was supplied (None) --> Use existing year from Series
60
// 2. Value was supplied and is a Scalar --> Create full Series of value
61
// 3. Value was supplied and is Series --> Update all elements with the non-null values
62
let year = if year.len() == 1 {
63
if let Some(value) = year.get(0) {
64
&Int32Chunked::full(PlSmallStr::EMPTY, value, n)
65
} else {
66
&ca.year()
67
}
68
} else {
69
&year.zip_with(&year.is_not_null(), &ca.year())?
70
};
71
let month = if month.len() == 1 {
72
if let Some(value) = month.get(0) {
73
&Int8Chunked::full(PlSmallStr::EMPTY, value, n)
74
} else {
75
&ca.month()
76
}
77
} else {
78
&month.zip_with(&month.is_not_null(), &ca.month())?
79
};
80
let day = if day.len() == 1 {
81
if let Some(value) = day.get(0) {
82
&Int8Chunked::full(PlSmallStr::EMPTY, value, n)
83
} else {
84
&ca.day()
85
}
86
} else {
87
&day.zip_with(&day.is_not_null(), &ca.day())?
88
};
89
let hour = if hour.len() == 1 {
90
if let Some(value) = hour.get(0) {
91
&Int8Chunked::full(PlSmallStr::EMPTY, value, n)
92
} else {
93
&ca.hour()
94
}
95
} else {
96
&hour.zip_with(&hour.is_not_null(), &ca.hour())?
97
};
98
let minute = if minute.len() == 1 {
99
if let Some(value) = minute.get(0) {
100
&Int8Chunked::full(PlSmallStr::EMPTY, value, n)
101
} else {
102
&ca.minute()
103
}
104
} else {
105
&minute.zip_with(&minute.is_not_null(), &ca.minute())?
106
};
107
let second = if second.len() == 1 {
108
if let Some(value) = second.get(0) {
109
&Int8Chunked::full(PlSmallStr::EMPTY, value, n)
110
} else {
111
&ca.second()
112
}
113
} else {
114
&second.zip_with(&second.is_not_null(), &ca.second())?
115
};
116
let nanosecond = if nanosecond.len() == 1 {
117
if let Some(value) = nanosecond.get(0) {
118
&Int32Chunked::full(PlSmallStr::EMPTY, value, n)
119
} else {
120
&ca.nanosecond()
121
}
122
} else {
123
&nanosecond.zip_with(&nanosecond.is_not_null(), &ca.nanosecond())?
124
};
125
126
let mut out = DatetimeChunked::new_from_parts(
127
year,
128
month,
129
day,
130
hour,
131
minute,
132
second,
133
nanosecond,
134
ambiguous,
135
&ca.time_unit(),
136
ca.time_zone().clone(),
137
ca.name().clone(),
138
)?;
139
140
// Ensure nulls are propagated.
141
if ca.has_nulls() {
142
out.physical_mut().merge_validities(ca.physical().chunks());
143
}
144
145
Ok(out)
146
}
147
148
/// Replace specific time component of a `DateChunked` with a specified value.
149
#[cfg(feature = "dtype-date")]
150
pub fn replace_date(
151
ca: &DateChunked,
152
year: &Int32Chunked,
153
month: &Int8Chunked,
154
day: &Int8Chunked,
155
) -> PolarsResult<DateChunked> {
156
let n = ca.len();
157
158
let year = if year.len() == 1 {
159
if let Some(value) = year.get(0) {
160
&Int32Chunked::full("".into(), value, n)
161
} else {
162
&ca.year()
163
}
164
} else {
165
&year.zip_with(&year.is_not_null(), &ca.year())?
166
};
167
let month = if month.len() == 1 {
168
if let Some(value) = month.get(0) {
169
&Int8Chunked::full("".into(), value, n)
170
} else {
171
&ca.month()
172
}
173
} else {
174
&month.zip_with(&month.is_not_null(), &ca.month())?
175
};
176
let day = if day.len() == 1 {
177
if let Some(value) = day.get(0) {
178
&Int8Chunked::full("".into(), value, n)
179
} else {
180
&ca.day()
181
}
182
} else {
183
&day.zip_with(&day.is_not_null(), &ca.day())?
184
};
185
let mut out = DateChunked::new_from_parts(year, month, day, ca.name().clone())?;
186
187
// Ensure nulls are propagated.
188
if ca.has_nulls() {
189
out.physical_mut().merge_validities(ca.physical().chunks());
190
}
191
192
Ok(out)
193
}
194
195