我有一个复杂的计算逻辑,这要求我从输入到apply_multiple创建一个新的Dataframe,以便利用DataFrame的功能,例如过滤器、Groupby、聚合等等,用于新的DF (在更广的Groupby聚合上下文中)。下面是一个非常简化的例子。注意,您需要功能"ndarray"来再现数学逻辑。首先,我通过一个名为Region的列来聚合我的df。
use polars::prelude::*;
use polars::df;
use ndarray::prelude::*;
use ndarray::stack;
pub fn main() {
let df = df! [
"Region" => ["EU", "EU", "EU", "EU", "US", "US", "US", "US"],
"Month" => ["NOV", "DEC", "APR", "APR", "JUL", "JAN", "JUL", "SEP"],
"Weight" => [1, 2, 3, 4, 5,6,7,8],
"Scalar" => [Some(0.3), None, Some(0.1), Some(0.1), Some(0.2), None, Some(0.1), Some(0.3)]
].unwrap();
let df1 = df.clone().lazy()
.groupby_stable([col("Region")])
.agg( [
// WHAT I WANT TO DO: if .first() then just returns nulls
region_health_index().first().alias("RegionHealth"),
// THIS THROWS AN ERROR: if .sum() then error
//region_health_index().sum().alias("RegionHealth2"),
]
)
.collect()
.unwrap();
dbg!(df1);
}df看起来如下所示:
Region ┆ Month ┆ Weight ┆ Scalar │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ i32 ┆ f64 │
╞════════╪═══════╪════════╪════════╡
│ EU ┆ NOV ┆ 1 ┆ 0.3 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ EU ┆ DEC ┆ 2 ┆ null │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ EU ┆ APR ┆ 3 ┆ 0.1 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ EU ┆ APR ┆ 4 ┆ 0.1 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ US ┆ JUL ┆ 5 ┆ 0.2 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ US ┆ JAN ┆ 6 ┆ null │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ US ┆ JUL ┆ 7 ┆ 0.1 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ US ┆ SEP ┆ 8 ┆ 0.3 │计算比例权重:
/// This function is for completeness of example only
pub fn weight_scaled() -> Expr {
col("Weight") * col("Scalar")
}这里的问题是,我需要按月聚合WeightScaled,而不是空值,然后执行一个复杂的数学计算。在欧盟的聚合之后,我想得到一系列的len 2: 0.3;0.7 --即1* 0.3和0.1 * 3+0.1 * 0.4,美国也是这样: 1.7;2.4。
另一个警告是,在实践中,我将有多个专栏。
在此之后,我执行复杂的计算,这要求我删除WeightScaled为null的月份。
我的尝试:
/// This function is supposed to return a SCALAR, per Group,
/// ie it would be lit::<f64>()
pub fn region_health_index() -> Expr {
apply_multiple(|columns| {
// Step 1. Here, I need to aggregate by Month
let df = DataFrame::new(vec![
columns[0].clone(), columns[1].clone()
])? // fails here
.lazy()
.groupby_stable([col("Month")])
.agg([
col("WeightScaled").sum().alias("WeightScaledSumed")
])
.collect()?;
// complex computation here
Ok( Series::new("result", &[res]) )
},
&[col("Month"), weight_scaled().alias("WeightScaled")],
GetOutput::from_type(DataType::Float64))
}如果调用region_health_index().sum(),错误是:
线程‘<= self.len()断言失败: idx.len() <= self.len()',C:\Users\Anato.cargo\registry\src\github.com-1ecc6299db9ec823\polars-core-0.22.3\src\frame\groupby\aggregations\mod.rsC:\Users\Anato.cargo\registry\src\github.com-1ecc6299db9ec823\polars-core-0.22.3\src\frame\groupby\aggregations\mod.rs::534534::1717
欧盟小组的res_m将是
-1.7 -1.3
-1.7 -1.3res是这些数字的之和,是-6。对于美国集团来说,这些只是复制issue.Similarly的虚拟值。因此,最终的结果应该是:
───────┬───────┬──
│ Region ┆ RegionHealth
│ --- ┆ --- ┆
│ str ┆ f64 ┆
╞════════╪═══════╪
│ EU ┆ -6 ┆
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌
│ US ┆ 0.82 发布于 2022-06-15 18:29:05
用df解决了!Apply_multiple中的宏:
let _df = df![
"a" => columns[0].clone(),
"b" => columns[1].clone(),
]?不知道最初创建df的方法为什么不起作用,可能是个bug。
https://stackoverflow.com/questions/72623491
复制相似问题