如何在Rust的Polars中为每行计算EBIT列的均值与标准差?
解决Polars中Rust函数的行级均值与标准差计算问题
核心思路
要实现行级的均值和标准差计算,关键是使用Polars提供的水平聚合函数(针对行维度计算的函数),替代之前按列统计或手动求和的方式。同时先筛选出所有符合前缀条件的目标列,再对这些列执行行级计算。
步骤1:筛选目标列
首先从输入DataFrame中提取所有列名以"Sum of EBIT [CY 2"开头的列,转换为Expr列表供后续计算使用:
use polars::prelude::*; fn industry_beta_f(mut raw_data: DataFrame, marginal_tax_rate: Expr) -> PolarsResult<DataFrame> { // 筛选所有以指定前缀开头的列 let ebit_cols: Vec<Expr> = raw_data .get_column_names() .iter() .filter(|name| name.starts_with("Sum of EBIT [CY 2")) .map(|name| col(name)) .collect(); // 后续计算逻辑... Ok(raw_data) }
步骤2:优化行级均值计算
替换手动求和除以10的方式,使用Polars内置的mean_horizontal函数,它会自动对每行的目标列计算均值,无需硬编码列数(即使后续年份数量变化也能兼容):
// 添加行级均值列 raw_data = raw_data.with_column( mean_horizontal(&ebit_cols) .alias("Average operating income (last 10 years)") )?;
步骤3:实现行级标准差计算
使用Polars的std_horizontal函数,指定自由度参数ddof(通常样本标准差用ddof=1,总体标准差用ddof=0,根据你的业务场景选择),实现行维度的标准差计算:
// 添加行级标准差列 raw_data = raw_data.with_column( std_horizontal(&ebit_cols) .ddof(1) .alias("Standard deviation in operating income (last 10 years)") )?;
完整函数示例
整合所有逻辑后的完整函数:
use polars::prelude::*; fn industry_beta_f(mut raw_data: DataFrame, marginal_tax_rate: Expr) -> PolarsResult<DataFrame> { // 筛选目标EBIT列 let ebit_cols: Vec<Expr> = raw_data .get_column_names() .iter() .filter(|name| name.starts_with("Sum of EBIT [CY 2")) .map(|name| col(name)) .collect(); // 计算行级均值并添加新列 raw_data = raw_data.with_column( mean_horizontal(&ebit_cols) .alias("Average operating income (last 10 years)") )?; // 计算行级标准差并添加新列(使用样本标准差ddof=1) raw_data = raw_data.with_column( std_horizontal(&ebit_cols) .ddof(1) .alias("Standard deviation in operating income (last 10 years)") )?; // 保留原有的marginal_tax_rate相关逻辑(如果有的话) // ... Ok(raw_data) }
关键说明
- 水平聚合函数(
mean_horizontal/std_horizontal)是Polars专门为行维度计算设计的API,比手动求和/统计更高效且不易出错。 - 避免硬编码列数(比如除以10),使用内置函数能自动适配目标列数量的变化,提升代码鲁棒性。
ddof参数的选择:如果你的数据是总体的全部样本,用ddof=0;如果是抽样数据,用ddof=1(默认值通常为1,可根据业务调整)。
内容的提问来源于stack exchange,提问作者Carlos Arias
相关产品推荐
相关产品推荐

