0

I'm trying to use arcpy from R via reticulate. For the most part, it works really well. However, I'm running into some issues when trying to do raster algebra. Consider the following code:

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

It seems that even though reticulate recognizes that the rasters are Python objects ("python.builtin.Raster" "python.builtin.object"), it doesn't know to use Python's + operator rather than R's. I tried importing arcpy with convert = FALSE but the error is the same.

I can get around this by defining Python functions to mimic the basic arithmetic operators.

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

source_python(tmp)

doublerast = add(randrast, randrast)

But obviously this is gets pretty cumbersome for more complex statements.

Does anyone know of a way to force reticulate to use Python's arithmetic operators for Python objects, rather than R's?

4

1 回答 1

1

一种选择是使用该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)
}

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

于 2018-03-01T21:03:06.323 回答