0

I am trying to account for a zero in the denominator when calculating a normalized percentage deviation from the term in the denominator.

Here is the code snippet -

let out: DataFrame = input_df
    .lazy()
    .with_columns(vec![
        when(col("write") == lit(0.0) && result.wr == 0.0)
            .then(lit(0.0))
            .otherwise((lit(result.wr) - col("write")) / col("write") * lit(100))
            .alias("write%"),
    ])
    .collect()
    .unwrap();

The problem is col("write") == lit(0.0) resolves to false even when the respective element in col("write") is 0.0. I'm unclear why or how to solve it.

col("write") is of type f64, so is result.wr.

I tried changing to just lit(0) which yielded the same result. Not using lit() throws a 'Expected Expr' error.

greybeard
  • 2,249
  • 8
  • 30
  • 66

1 Answers1

0

There are a few issues here. The first being a logical one. You are stating you want to account for a zero in the denominator, however the following line will only ever evaluate to true if zero is in the denominator and the numerator:

when(col("write") == lit(0.0) && result.wr == 0.0)

The second issue is with the ==, when comparing column values to literals, you should be using the built-in expressions for the columns. In this case, you can use col("write").eq(lit(0.0)).

Here's a working example, note that I removed the numerator check as it's not needed:

let mut input_df = df!("write" => &[0.0, 3.0, 999.0]).unwrap();
let wr = 66.0;

let out: DataFrame = input_df
    .lazy()
    .with_columns(vec![
            when(col("write").eq(lit(0.0)))
                    .then(lit(0.0))
                    .otherwise((lit(wr) - col("write")) / col("write") * lit(100))
                    .alias("write%"),
    ])
    .collect()
    .unwrap();

println!("{:?}", out);

And the output:

shape: (3, 2)

┌───────┬────────────┐
│ write ┆ write%     │
│ ---   ┆ ---        │
│ f64   ┆ f64        │
╞═══════╪════════════╡
│ 0.0   ┆ 0.0        │
│ 3.0   ┆ 2100.0     │
│ 999.0 ┆ -93.393393 │
└───────┴────────────┘
emagers
  • 841
  • 7
  • 13