来自 Reticulate 的 Arcpy 地图代数

Arcpy map algebra from reticulate

我正在尝试通过 reticulate 从 R 使用 arcpy。在大多数情况下,它工作得很好。但是,在尝试进行栅格代数时,我 运行 遇到了一些问题。考虑以下代码:

library(reticulate)
use_python("C:/Python27/ArcGISx6410.2")

arcpy = import("arcpy")
arcpy$CheckOutExtension("Spatial")

arcpy$management$CreateRandomRaster("in_memory", 
  "randrast", "NORMAL 3.0", "0 0 500 500", 50)

randrast = arcpy$sa$Raster("in_memory/randrast")

doublerast = randrast + randrast 

Error in randrast + randrast : non-numeric argument to binary operator

似乎即使 reticulate 识别光栅是 Python 对象 ("python.builtin.Raster" "python.builtin.object"),它也不知道使用 Python 的 + 运算符而不是 R 的。我尝试用 convert = FALSE 导入 arcpy 但错误是一样的。

我可以通过定义 Python 函数来模拟基本算术运算符来解决这个问题。

tmp = tempfile(fileext = ".py")
cat("def add(x, y):\n  return x + y\n", file = tmp)

source_python(tmp)

doublerast = add(randrast, randrast)

但显然,对于更复杂的语句,这会变得非常麻烦。

有人知道强制 reticulate 对 Python 对象使用 Python 的算术运算符而不是 R 的方法吗?

一种选择是使用 operator 模块为 Python 对象定义我自己的运算符:

`%py+%` = function(e1, e2) {
  op = import("operator")
  op$add(e1, e2)
}

doublerast = randrast %py+% randrast 

或者,或者,使用 S3 类 重载算术运算符(如对 TensorFlow 所做的那样)以支持 python.builtin.object,例如

`+.python.builtin.object` = function(e1, e2) {
  op = import("operator")
  op$add(e1, e2)
}

但我担心操作顺序可能无法按预期运行。