polars_lazy/dsl/
functions.rs1use polars_core::prelude::*;
7pub use polars_plan::dsl::functions::*;
8use polars_plan::prelude::UnionArgs;
9
10use crate::prelude::*;
11
12pub(crate) fn concat_impl<L: AsRef<[LazyFrame]>>(
13 inputs: L,
14 args: UnionArgs,
15) -> PolarsResult<LazyFrame> {
16 let mut inputs = inputs.as_ref().to_vec();
17
18 let lf = std::mem::take(
19 inputs
20 .get_mut(0)
21 .ok_or_else(|| polars_err!(NoData: "empty container given"))?,
22 );
23
24 let opt_state = lf.opt_state;
25 let cached_arenas = lf.cached_arena.clone();
26
27 let mut lps = Vec::with_capacity(inputs.len());
28 lps.push(lf.logical_plan);
29
30 for lf in &mut inputs[1..] {
31 let lp = std::mem::take(&mut lf.logical_plan);
32 lps.push(lp)
33 }
34
35 let lp = DslPlan::Union { inputs: lps, args };
36 Ok(LazyFrame::from_inner(lp, opt_state, cached_arenas))
37}
38
39#[cfg(feature = "diagonal_concat")]
40pub fn concat_lf_diagonal<L: AsRef<[LazyFrame]>>(
43 inputs: L,
44 mut args: UnionArgs,
45) -> PolarsResult<LazyFrame> {
46 args.diagonal = true;
47 concat_impl(inputs, args)
48}
49
50pub fn concat_lf_horizontal<L: AsRef<[LazyFrame]>>(
52 inputs: L,
53 args: UnionArgs,
54) -> PolarsResult<LazyFrame> {
55 let lfs = inputs.as_ref();
56 let (opt_state, cached_arena) = lfs
57 .first()
58 .map(|lf| (lf.opt_state, lf.cached_arena.clone()))
59 .ok_or_else(
60 || polars_err!(NoData: "Require at least one LazyFrame for horizontal concatenation"),
61 )?;
62
63 let options = HConcatOptions {
64 parallel: args.parallel,
65 strict: args.strict,
66 };
67 let lp = DslPlan::HConcat {
68 inputs: lfs.iter().map(|lf| lf.logical_plan.clone()).collect(),
69 options,
70 };
71 Ok(LazyFrame::from_inner(lp, opt_state, cached_arena))
72}
73
74pub fn concat<L: AsRef<[LazyFrame]>>(inputs: L, args: UnionArgs) -> PolarsResult<LazyFrame> {
76 concat_impl(inputs, args)
77}
78
79#[cfg(test)]
80mod test {
81 #[allow(unused_imports)]
83 use super::*;
84
85 #[test]
86 #[cfg(feature = "diagonal_concat")]
87 fn test_diag_concat_lf() -> PolarsResult<()> {
88 let a = df![
89 "a" => [1, 2],
90 "b" => ["a", "b"]
91 ]?;
92
93 let b = df![
94 "b" => ["a", "b"],
95 "c" => [1, 2]
96 ]?;
97
98 let c = df![
99 "a" => [5, 7],
100 "c" => [1, 2],
101 "d" => [1, 2]
102 ]?;
103
104 let out = concat_lf_diagonal(
105 &[a.lazy(), b.lazy(), c.lazy()],
106 UnionArgs {
107 rechunk: false,
108 parallel: false,
109 ..Default::default()
110 },
111 )?
112 .collect()?;
113
114 let expected = df![
115 "a" => [Some(1), Some(2), None, None, Some(5), Some(7)],
116 "b" => [Some("a"), Some("b"), Some("a"), Some("b"), None, None],
117 "c" => [None, None, Some(1), Some(2), Some(1), Some(2)],
118 "d" => [None, None, None, None, Some(1), Some(2)]
119 ]?;
120
121 assert!(out.equals_missing(&expected));
122
123 Ok(())
124 }
125}