into_shape after remove_index fails



我有一个具有309.760个元素的&[f64]。这个数据集是一个包含7040个属性集的数组。每个属性集包含一对f64s和14个f64三元组。

我只对三胞胎感兴趣。

我可以像这样读取这个数据集到narray中:

let array = Array::from_iter(data);
let mut propertysets = vector.into_shape(IxDyn(&[7040, 44])).unwrap();

,我可以像这样删除每个属性集的前两个f64:

propertysets.remove_index(Axis(1), 0);
propertysets.remove_index(Axis(1), 0);
println!("{:?}", propertysets.shape()); // [7040, 42]

看起来很有希望。但现在我想重塑数组为[7040,14,3],这应该工作,因为3 * 14 = 42,但:

let result = propertysets.into_shape(IxDyn(&[7040, 14, 3])).unwrap();

对这条消息感到恐慌:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ShapeError/IncompatibleLayout: incompatible memory layout'

remove_index的文档说:

元素不会被取消初始化或删除,只是被移出视图

这可能解释了为什么这个失败。但是怎样才能做到呢?我是否必须以某种方式复制propertysets到正确形状的新数组中?但如何?

使用Array::from_iter(propertysets.iter())将导致&f64而不是f64的narray。

要使into_shape操作生效,数组必须在内存中是c-连续的或fortrans -连续的(参见文档)。在

vector.into_shape(IxDyn(&[7040, 44])).unwrap();

它们是连续的。但在

propertysets.remove_index(Axis(1), 0); 

它们不是。为什么?整个数组不会被remove_index移动。元素被移出视图(参见文档)。

如何解决?

  1. 使用from_shape_vec重组
  2. 使用新的to_shape函数。(不是文档,但这里有一些信息和大量的例子在这里)

例子:

use ndarray::{Array, Order, ViewRepr};
use ndarray::IxDyn;
use ndarray::Axis;
use ndarray::ArrayBase;
use ndarray::CowRepr;
use ndarray::Dim;
use ndarray::OwnedRepr;
fn into_shape_reassemble(data: Vec<f64>) -> Array<f64, IxDyn>
{
let array = Array::from_iter(data);
let mut result = array.into_shape(IxDyn(&[7040, 44])).unwrap();
result.remove_index(Axis(1), 0);
result.remove_index(Axis(1), 0);
let result = Array::from_shape_vec((7040, 42), result.iter().cloned().collect()).unwrap();
let result = result.into_shape(IxDyn(&[7040, 14, 3])).unwrap();
println!("{:?}", result.shape());
result
}
fn to_shape(data: Vec<f64>) -> ArrayBase<OwnedRepr<f64>, IxDyn>
{
let array = Array::from_iter(data);
let mut result = array.into_shape(IxDyn(&[7040, 44])).unwrap();
result.remove_index(Axis(1), 0);
result.remove_index(Axis(1), 0);
let result = result.to_shape((7040, 14, 3)).unwrap().to_owned();
println!("{:?}", result.shape());
result.into_dyn()
}
#[cfg(test)]
mod tests {
#[test]
fn test_into_shape() {
let data = vec![0.; 7040 * 44];
super::into_shape_reassemble(data);
}
#[test]
fn test_to_shape() {
let data = vec![0.; 7040 * 44];
super::to_shape(data);
}
}

输出:

[7040, 14, 3]
[7040, 14, 3]

最新更新