Skip to main content

polars_core/frame/
broadcast.rs

1use polars_error::{PolarsResult, polars_bail};
2
3use crate::frame::column::Column;
4
5pub(super) fn infer_broadcast_height(columns: &[Column]) -> usize {
6    if columns.is_empty() {
7        return 0;
8    }
9
10    columns
11        .iter()
12        .map(|c| c.len())
13        .find(|len| *len != 1)
14        .unwrap_or(1)
15}
16
17/// Broadcasts to `height`. Errors if a column has non-unit length that does not match `height`.
18/// Does not check name duplicates.
19pub(super) fn broadcast_columns(height: usize, columns: &mut [Column]) -> PolarsResult<()> {
20    for col in columns.iter_mut() {
21        // Length not equal to the broadcast len, needs broadcast or is an error.
22        let len = col.len();
23        if len != height {
24            if len != 1 {
25                let name = col.name().clone();
26
27                let extra_info = if let Some(c) = columns.iter().find(|c| c.len() == height) {
28                    format!(" (matching column '{}')", c.name())
29                } else {
30                    String::new()
31                };
32
33                polars_bail!(
34                    ShapeMismatch:
35                    "could not create a new DataFrame: \
36                    series {name:?} has length {len} \
37                    while trying to broadcast to length {height}{extra_info}",
38                );
39            }
40            *col = col.new_from_index(0, height);
41        }
42    }
43
44    Ok(())
45}