Я пытаюсь реализовать ускоренный доверительный интервал с коррекцией смещения в Rust. Моя функция metric принимает фрейм данных Rust и выполняет над ним некоторые операции, чтобы вернуть f64. В приведенном ниже примере очевидно, что .lazy() не нужен, но реальная функция его требует (она требует group_bys и т. д.). Чтобы определить доверительный интервал bCa, необходимо вычислить метрику исходной выборки. Второй шаг — сделать складной нож, вычислив метрику на выборке с удаленной i-й строкой. Проблема в том, что без .clone() на первом этапе Rust жалуется на «заимствование перемещенного значения». Если я изменю metric, чтобы получить ссылку, то мне придется либо клонировать внутри функции, либо разыменовать внутри функции, либо я получу сообщение «не могу выйти из общей ссылки». Можно ли избежать этого клона, или клон очень дешевый и мне не стоит об этом беспокоиться?
use polars::prelude::*;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
fn metric(df: DataFrame) -> f64 {
df.lazy().collect().unwrap()["x"].sum().unwrap()
}
pub fn bca_confidence_interval(df: DataFrame) -> (f64, f64, f64) {
let df_height = df.height();
let stat_original = metric(df.clone());
let index = ChunkedArray::new("index", 0..df_height as u64);
let jacknife_stats: Vec<f64> = (0..df_height)
.into_par_iter()
.map(|i| metric(df.filter(&index.not_equal(i)).unwrap()))
.filter(|x| !x.is_nan())
.collect();
(0.0, 1.0, 2.0)
}

.clone() довольно дешево. Я бы не беспокоился об этом.
DataFrame просто содержит Vec<Series> для своих столбцов, а Series просто содержит Arc<_>. Arcs облегчают совместное владение, поэтому клон просто увеличивает счетчик. Таким образом, при клонировании кадра данных не требуется массивной глубокой копии; данные являются общими.
Клонирование DataFrame обходится дешево: stackoverflow.com/a/72328127.