79333895

Date: 2025-01-06 17:55:57
Score: 0.5
Natty:
Report link

There were a few problems that @jqurious pointed out and would like to provide a solution.

  1. Changed geometric_mean() function to take in a Float64Chuck instead of a &[f64]
  2. gmean() function, passed the series name into the new Float64Chunked array, instead of using Series::from_iter().
  3. when using lit(1.0) at the beginning of an expression, this will cause the error above "the name 'literal' is duplicate".

For example, the literal error is caused by having lit(1.0) in front of + self.gmean()

fn gmean_annualized_expr(self, freq:Option<&str>) -> Expr {
        let annualize_factor = lit(annualize_scaler(freq).unwrap());
        ( lit(1.0) + self.gmean()).pow(annualize_factor) - lit(1.0)
    }

By moving lit(1.0) after self.gmean() fixed the problem.

fn gmean_annualized_expr(self, freq:Option<&str>) -> Expr {
        let annualize_factor = lit(annualize_scaler(freq).unwrap());
        (self.gmean() + lit(1.0)).pow(annualize_factor) - lit(1.0)
    }

Here is the full expression for reference

fn geometric_mean(values: &Float64Chunked) -> f64 {
    let adjusted_values: Float64Chunked = values.apply(|opt_v| opt_v.map(|x| x + 1.0));
    let product: f64 = adjusted_values
        .into_iter()
        .filter_map(|opt| opt) // Remove None values
        .product(); // Compute the product of present values
    let count = adjusted_values.len() as f64;
    product.powf(1.0 / count)
}

fn gmean(series: &[Series]) -> PolarsResult<Series> {

    let _series = &series[0]; // This is getting the actual values from the series since there are multiple types of data returns from a series
    let _chunk_array = _series.f64()?;

    let geo_mean= geometric_mean(_chunk_array) - 1.0;
    let new_chunk = Float64Chunked::from_vec(_series.name().clone(), vec![geo_mean]);

    Ok(new_chunk.into_series())
}


fn gmean_column(series: &Column) -> Result<Option<Column>,PolarsError> {
    let materialized_series_slice = std::slice::from_ref(series.as_materialized_series());
    Ok(Some(gmean(materialized_series_slice)?.into_column()))

}

pub trait GeoMean {
    fn gmean(self) -> Expr;
}

impl GeoMean for Expr {
    fn gmean(self) -> Expr {
        self.apply(|column| gmean_column(&column),GetOutput::from_type(DataType::Float64))
    }
}


Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @jqurious
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Trevor Seibert