scala中的数组更新(相当于NumPy广播分配)

2024-06-17 15:06:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习Scala,现在我正在将一段代码从Python翻译成Scala。在

我有两个大致类似的函数:

def inner_function(arr):
    scratch = np.zeros(arr.shape)

    do_sth(arr, scratch)            # modifies scratch, doesn't modify arr
    do_sth_else(arr, scratch)       # as above

    arr[...] = scratch              # here's the broadcast assignment

def outer_function():
    arr = np.zeros((height, width))

    for _ in range(its):
        inner_function(arr)

    # do other things...

除了arr[...] = scratch部分之外,所有的翻译都很好。据我所知,最接近的等价物应该是for (x <- 0 until width) for (y <- 0 until height) arr(y)(x) = scratch(y)(x),但它看起来很难看,而且远没有达到最佳效果。在

因此,我做了一个变通方法,将赋值移到外部函数并使用可变引用:

^{2}$

但是,我仍然想知道是否有一种方法可以更接近原始代码来编写它。(在所有索引上没有显式循环。)

有没有一种方法,也许,打算用另一个数组的元素替换一个数组的全部内容?在


Tags: 函数代码fordefnpzerosfunctionwidth
1条回答
网友
1楼 · 发布于 2024-06-17 15:06:02
scratch.copyToArray(arr)

请注意,它不会复制内部数组,因此如果您的do_sth和{}执行类似于scratch(i) = arr(j)的操作,它将无法按预期工作。对于这种情况,您确实需要一个循环,但它可以简单得多:

^{pr2}$

然而,您的第二个解决方案只是更好。它消除了不必要的额外工作(复制数组)它消除了不必要的副作用(包括上一段中的问题!)(编辑:这是错误的;例如,如果您这样做,scratch(0) = arr(0); scratch(1) = arr(0)我认为在下一步中,您的Python代码将在arr(0)和{}中使用不同的数组,但是Scala代码将有两个对同一数组的引用)。您还可以删除var

def outerFunction() = 
  (0 until its).foldLeft(Array.fill(height, width)(0)) { (arr, _) => innerFunction(arr) }

或者

def outerFunction() = 
  Function.chain(Stream.fill(its)(innerFunction _)).apply(Array.fill(height, width)(0))

相关问题 更多 >