在Rust中如何对两个ndarray执行拉链(Zip)操作?
在Rust中如何对两个ndarray执行拉链(Zip)操作?
嘿,我知道你已经会单独遍历ndarray的行或者列了,就像你写的这段代码:
use ndarray::array; fn main() { let a = array![[1, 5], [3, 7]]; let b = array![[2, 4], [8, 6]]; for row in a.rows() { println!("{:?}", row); } for row in b.rows() { println!("{:?}", row); } }
这段代码的输出是:
[1, 5], shape=[2], strides=[1], layout=CFcf (0xf), contiguous [3, 7], shape=[2], strides=[1], layout=CFcf (0xf), contiguous [2, 4], shape=[2], strides=[1], layout=CFcf (0xf), contiguous [8, 6], shape=[2], strides=[1], layout=CFcf (0xf), contiguous
如果想要把两个数组的行一一对应起来做拉链操作(也就是同时遍历a的行和b的行),其实ndarray库本身就提供了很方便的Zip工具来实现这种多数组的并行遍历。我们可以这样改:
首先引入ndarray::Zip,然后用Zip::from(a.rows()).and(b.rows()).for_each()来同时处理每一对行:
use ndarray::{array, Zip}; fn main() { let a = array![[1, 5], [3, 7]]; let b = array![[2, 4], [8, 6]]; Zip::from(a.rows()) .and(b.rows()) .for_each(|row_a, row_b| { println!("a的行: {:?}, b的行: {:?}", row_a, row_b); }); }
运行之后,输出就会把两个数组对应的行配对展示:
a的行: [1, 5], shape=[2], strides=[1], layout=CFcf (0xf), contiguous, b的行: [2, 4], shape=[2], strides=[1], layout=CFcf (0xf), contiguous a的行: [3, 7], shape=[2], strides=[1], layout=CFcf (0xf), contiguous, b的行: [8, 6], shape=[2], strides=[1], layout=CFcf (0xf), contiguous
另外,如果你不仅是要遍历,还想对对应元素做计算生成新数组,Zip也能轻松搞定。比如把两个数组对应位置的元素相加,生成新数组:
use ndarray::{array, Zip, Array2}; fn main() { let a = array![[1, 5], [3, 7]]; let b = array![[2, 4], [8, 6]]; let mut result = Array2::zeros(a.dim()); Zip::from(&mut result) .and(&a) .and(&b) .for_each(|res, &x, &y| { *res = x + y; }); println!("相加后的结果: {:?}", result); }
这段代码的输出就是:
相加后的结果: [[3, 9], [11, 13]]
是不是很省心?Zip会自动处理数组的维度匹配,只要两个数组形状一致,就能轻松实现并行遍历和操作啦~
备注:内容来源于stack exchange,提问作者Roger V.
相关产品推荐
相关产品推荐

