You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Polars中Series::series_equal为何在值不同时测试仍通过?

为什么调用Series::series_equal后测试仍通过,而assert_eq!会触发断言失败?

问题场景

我编写了转换函数convert_tb_to_tib,测试时发现明明两个Series的数值存在明显差异(索引0处预期值为100.94947,实际计算值为90.94947),但直接调用Series::series_equal方法的测试居然通过了;换成assert_eq!宏时,测试就会触发断言失败并报错。

相关代码:

pub fn convert_tb_to_tib(s: Series) -> Series {
    let result = s.cast(&DataType::Float64).unwrap() * 0.90949470177293;
    result
}

// 测试通过的代码
fn test_convert_tb_to_tib() {
    let test_s = Series::new("", &[100, 200, 300, 400]);
    let transformed_s = convert_tb_to_tib(test_s);
    let expected_s = Series::new("", &[100.94947, 181.89894, 272.848411, 373.797881]);
    transformed_s.series_equal(&expected_s);
}
// 测试结果:test wrangle::tests::test_convert_tb_to_tib ... ok

改用assert_eq!后的代码及报错:

fn test_convert_tb_to_tib() {
    let test_s = Series::new("", &[100, 200, 300, 400]);
    let transformed_s = convert_tb_to_tib(test_s);
    let expected_s = Series::new("", &[100.94947, 181.89894, 272.848411, 373.797881]);
    assert_eq!(transformed_s, expected_s);
}

报错信息:
thread 'wrangle::tests::test_convert_tb_to_tib' panicked at 'assertion failed: (left == right)
left: shape: (4,) Series: '' [f64] [ 90.94947 181.89894 272.848411 363.797881 ],
right: shape: (4,) Series: '' [f64] [ 100.94947 181.89894 272.848411 373.797881 ]', src/wrangle.rs:108:9

原因分析

  1. 测试通过的核心原因:未断言series_equal的返回值
    Rust的测试规则很简单:只要测试函数执行过程中没有触发panic,就会标记为"ok"。你在第一个测试里只是调用了series_equal方法,但没有把它的返回值传给断言宏(比如assert!),所以不管这个方法返回true还是false,测试都会顺利执行完毕,不会触发失败。

  2. assert_eq!失败的原因:严格的相等比较
    assert_eq!依赖于类型的PartialEq trait实现,Polars的Series对PartialEq的实现是严格的数值相等校验(哪怕是浮点数,也要求精确匹配)。当两个Series的数值存在差异时,==会返回false,触发assert_eq!的panic。

修正测试的方法

如果想让series_equal的结果影响测试结果,需要将它的返回值用assert!宏包裹:

fn test_convert_tb_to_tib() {
    let test_s = Series::new("", &[100, 200, 300, 400]);
    let transformed_s = convert_tb_to_tib(test_s);
    let expected_s = Series::new("", &[100.94947, 181.89894, 272.848411, 373.797881]);
    // 断言series_equal的结果为true,否则测试失败
    assert!(transformed_s.series_equal(&expected_s));
}

另外,series_equal默认支持浮点数的近似比较(可以通过epsilon参数调整容忍度),这也是它和PartialEq严格比较的区别,但在你的场景里,核心问题还是没有对series_equal的返回值做断言。


内容的提问来源于stack exchange,提问作者NotABot83

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:50:41