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

pad*_*dyg 6 multidimensional-array rust

以下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]
Run Code Online (Sandbox Code Playgroud)

这有简单的等价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();
...
Run Code Online (Sandbox Code Playgroud)

我知道我无法将它减少到numpy one liner

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

但我想也许一些map或zip变种或宏可能对我有所帮助.

E_n*_*ate 10

这可以通过与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]);
}
Run Code Online (Sandbox Code Playgroud)

使用slice_muts!用于定义预期范围的宏来完成切片.切片的结果是一个可变数组视图,因此,大多数操作ArrayBase都可用,包括算术运算.通过广播规则形状的右旋阵列[4]可以自动广播到形状的一个[100, 4]+=操作者.


如果从Python到Rust的ndarraycrate 过渡中存在其他混淆,则该文档包含Python用户指南.

  • @Ploppz `ArrayBase` 有一个 [`assign`](https://docs.rs/ndarray/0.12.1/ndarray/struct.ArrayBase.html#method.assign) 方法,应该可以解决问题。 (2认同)