是否有一个 Rust ndarray 等效于切片上的 numpy 算术



下面的 Python 代码将重复添加向量[1, 2, 3, 4]到二维数组a中的每一行,仅从第 20 行开始。

import numpy as np
# an array of shape (100, 4)
a = np.zeros((100, 4), dtype=np.float32)
# and this is the operation explained above
a[20:, :] += [1.0, 2.0, 3.0, 0.0]

ndarray有一个简单的等价物吗? 我已经可以用更复杂的凌乱代码做我需要的事情,但觉得可能有一个整洁 ndarray.rs 等效的。

好吧,冒着使我认为可能有一个我无法挖掘的简单答案的问题过于复杂化的风险......

我正在使用 f32 形状 (n, 8) 的数组,表示三个顶点位置、三个法线组件和两个纹理映射坐标。我正在将来自多个 3D 对象的缓冲区合并为一个,以实现更高效的图形渲染。在 8 个宽数组中,需要缩放前三个值,即乘以&[sx, sy, sz]然后使用标准rz.dot(&rx.dot(&ry.dot()))函数旋转,最后添加一个位移&[dx, dy, dz]。法线只需要旋转。我目前的系统涉及将数据保存在中间数组变量中。

use ndarray as nd;
array_buffer: nd::Array2<f32>, loc: &[f32; 3], scl: &[f32; 3]...
...
// scale then rotate new verts then add displacement
let new_verts = &new_buf.array_buffer.slice(s![.., 0..3]) * &nd::arr1(scl);
let new_verts = rotate_vec(rot, &new_verts) + &nd::arr1(loc);
// then add them to existing verts
let mut verts = nd::stack(nd::Axis(0),
&[old_buf.array_buffer.slice(s![.., 0..3]),
new_verts.view()]).unwrap();
...

我知道我无法将其简化为numpy one衬垫

verts = np.append(old_buf.array_buffer[:,0:3], 
rotate_vec(rot, (new_buf.array_buffer[:,0:3] * scl) + loc))

但我认为也许一些地图或 zip 变体或宏可能会对我有所帮助。

这可以通过与 Python 中相同的两个步骤来完成:切片,然后添加分配给广播右手数组。

use ndarray::Array2;
let mut a: Array2<f32> = Array2::zeros((100, 4));
{ 
let mut slice = a.slice_mut(s![20.., ..]);
slice += &ArrayView::from(&[1.0, 2.0, 3.0, 4.0]);
}

切片是使用slice_mut和用于定义预期范围的s!宏完成的。切片的结果是一个可变的数组视图,因此,ArrayBase中看到的大多数操作都是可用的,包括算术操作。 通过广播规则,形状[4]的右手数组可以自动广播到+=运算符的形状[100, 4]之一。


如果在从 Python 到 Rust 的ndarraycrate 的过渡过程中出现其他混淆,文档包含 Python 用户指南。

最新更新