英文:
How to check if element value in Rust-Polars column is 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 an 'Expected Expr' error.
英文:
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.
答案1
得分: 1
这里有一些问题。首先是逻辑问题。您表示要考虑分母中的零,然而以下一行仅在零在分母中且分子为零时才会评估为true:
when(col("write") == lit(0.0) && result.wr == 0.0)
第二个问题涉及到==
,在比较列值和文字值时,您应该使用内置的列表达式。在这种情况下,您可以使用col("write").eq(lit(0.0))
。
以下是一个工作示例,注意我删除了分子检查,因为它不是必要的:
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);
输出如下:
形状:(3, 2)
┌───────┬────────────┐
│ write ┆ write% │
│ --- ┆ --- │
│ f64 ┆ f64 │
╞═══════╪════════════╡
│ 0.0 ┆ 0.0 │
│ 3.0 ┆ 2100.0 │
│ 999.0 ┆ -93.393393 │
└───────┴────────────┘
英文:
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 │
└───────┴────────────┘
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论