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

Rust编译错误E0596:DataFrame迭代可变借用失败解决方案

解决Polars DataFrame逐行迭代的Rust E0596错误

问题场景

编写了一段处理Polars DataFrame的Rust代码,意图逐行迭代原DataFrame并生成新的处理后DataFrame,但编译时触发E0596错误。

原代码

fn iter_and_make_feature_dataframe(df: &DataFrame) {
    // iter over rows
    // let columns = columns.unwrap_or(vec![]);
    let col_len = df.shape().1;
    let columns = df.get_column_names();

    let mut df = df.clone();
    df.as_single_chunk();

    let mut iters = df.iter().map(|s| s.iter()).collect::<Vec<_>>();

    let mut row: Vec<Vec<String>> = Vec::new();
    for row_idx in 0..df.height() {
        let mut c_row: Vec<String> = Vec::new();
        for iter in &mut iters.iter().zip(&columns) {
            let (value_iter, col_name) = iter;
            let value = value_iter
                .next()
                .expect("should have as many iterations as rows")
                .to_string();
            c_row.push(value);
        }

        // process row
    }
}

编译错误

error[E0596]: cannot borrow `*value_iter` as mutable, as it is behind a `&` reference
  --> src/main.rs:24:25
   |
23 |               let (value_iter, col_name) = iter;
   |                    ---------- consider changing this binding's type to be: `&mut SeriesIter<'_>`
24 |               let value = value_iter
   |  _________________________^
25 | |                 .next()
   | |_______________________^ `value_iter` is a `&` reference, so the data it refers to cannot be borrowed as mutable

解决方案

错误原因

iters.iter()返回的是不可变迭代器,每个元素是&SeriesIter,而SeriesIter::next()方法需要可变引用(调用后迭代器内部状态会改变),因此无法调用next()触发错误。

修改后的代码

use polars::prelude::*;

fn iter_and_make_feature_dataframe(df: &DataFrame) {
    let columns = df.get_column_names();

    let mut df = df.clone();
    df.as_single_chunk();

    let mut iters = df.iter().map(|s| s.iter()).collect::<Vec<_>>();

    let mut processed_rows: Vec<Vec<String>> = Vec::new();
    for _ in 0..df.height() {
        let mut current_row: Vec<String> = Vec::new();
        // 改用iter_mut()获取可变迭代器,同时调整columns的迭代方式
        for (value_iter, col_name) in iters.iter_mut().zip(columns.iter()) {
            let value = value_iter
                .next()
                .expect("row count mismatch")
                .to_string();
            current_row.push(value);
        }

        // 这里添加你的行处理逻辑
        processed_rows.push(current_row);
    }

    // 可选:将处理后的行转换为新DataFrame
    let new_df = DataFrame::new(
        columns.into_iter()
            .enumerate()
            .map(|(idx, name)| {
                let column_values: Vec<String> = processed_rows.iter().map(|row| row[idx].clone()).collect();
                Series::new(name, column_values)
            })
            .collect()
    ).expect("failed to create new DataFrame");
}

关键改动点

  • 将&mut iters.iter().zip(&columns)替换为iters.iter_mut().zip(columns.iter()):iter_mut()返回可变引用的迭代器,确保value_iter是&mut SeriesIter,满足next()方法的可变借用要求。
  • 调整变量命名(如row改为processed_rows)提升代码可读性。
  • 补充了将处理后的行转换为新DataFrame的示例逻辑,贴合生成新表的需求。

更简洁的Polars原生方案

Polars提供了row_iter()方法可以直接逐行迭代DataFrame,无需手动管理列迭代器,代码更简洁且符合Polars的惯用写法:

use polars::prelude::*;

fn iter_and_make_feature_dataframe(df: &DataFrame) {
    let columns = df.get_column_names().to_vec();
    let mut processed_columns: Vec<Vec<String>> = vec![Vec::new(); columns.len()];

    // 使用row_iter()直接迭代每一行
    for row in df.row_iter() {
        let mut processed_row = Vec::new();
        for (idx, value) in row.iter().enumerate() {
            let processed_value = value.to_string(); // 替换为你的实际处理逻辑
            processed_row.push(processed_value.clone());
            processed_columns[idx].push(processed_value);
        }
    }

    // 生成新DataFrame
    let new_df = DataFrame::new(
        columns.into_iter()
            .zip(processed_columns)
            .map(|(name, values)| Series::new(name, values))
            .collect()
    ).expect("failed to create new DataFrame");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:37:02