如何在 `polars::prelude::DataFrame` 上使用 `ndarray_stats::CorrelationExt`?

How do I use `ndarray_stats::CorrelationExt` on a `polars::prelude::DataFrame`?

我正在尝试计算 Rust 中数据框的协方差。 ndarray_stats 板条箱定义了 such a function for arrays, and I can produce an array from a DataFrame using to_ndarray。如果我使用文档中的示例 (a),编译器会很高兴,但是如果我尝试在 DataFrame 生成的 Array2 上使用它,这将不起作用:

use polars::prelude::*;
use ndarray_stats::CorrelationExt;

fn cov(df: &DataFrame) -> Vec<f64> {
    // Both of these are Array2<f64>s
    let mat = df.to_ndarray::<Float64Type>().unwrap();
    let a = arr2(&[[1., 3., 5.], [2., 4., 6.]]);

    let x = a.cov(1.).unwrap();
    let y = mat.cov(1.).unwrap();
}
   |
22 |     let y = mat.cov(1.).unwrap();
   |                 ^^^ method not found in `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>`

为什么编译器允许定义x而不是y?我怎样才能修复代码以便可以分配 y

这是依赖版本不匹配。polars-core depends on ndarray version 0.13.x as of 0.14.7,而 ndarray-stats 0.5 requires ndarray 0.15。当您在项目中使用最新版本的 ndarray 时,x 的二维数组类型将与 ndarray-stats 提供的扩展特征 CovExt 兼容,但是 y不会。

无论库中类型的性质如何,一旦包含库的多个 semver 不兼容版本,它们的类型通常是不可互换的。换句话说,即使这些 Array2<_> 可能看起来是同一类型,但编译器会将它们视为不同类型。

可以通过检查 cargo tree -d 的输出来找到包中 crate 的多个版本,它只显示重复的依赖项和显示依赖于它们的 crate 的反向树。重复不一定会造成问题,但如果项目直接消耗一个以上API就会出现问题。

撰写本文时的最低公分母是将 ndarray 降级为 0.13,将 ndarray-stats 降级为 0.3,即 also has the method cov。也可能值得考虑为 polars 项目做贡献,以便在那里更新 ndarray