英文:
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 │
└───────┴────────────┘
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论