【问题标题】:Error in running a Python code from R with the package rPithon使用包 rPithon 从 R 运行 Python 代码时出错
【发布时间】:2016-11-18 00:13:22
【问题描述】:

我想从 R 运行这个 Python 代码:

>>> import nlmpy 
>>> nlm = nlmpy.mpd(nRow=50, nCol=50, h=0.75) 
>>> nlmpy.exportASCIIGrid("raster.asc", nlm)

Nlmpy 是一个用于构建中性景观模型的 Python 包。示例来自website

为了从 R 运行这个 Python 代码,我正在尝试使用包 rPithon。但是,我收到此错误消息:

if (pithon.available()) 
{ 
  nRow <- 50 
  nCol <- 50 
  h <- 0.75 

  # this file contains the definition of function concat 
  pithon.load("C:/Users/Anaconda2/Lib/site-packages/nlmpy/nlmpy.py") 
  pithon.call( "mpd", nRow, nCol, h) 

} else { 
  print("Unable to execute python") 
} 

Error in pithon.get("_r_call_return", instance.name = instname) : 
Couldn't retrieve variable: Traceback (most recent call last): 
File "C:/Users/Documents/R/win-library/3.3/rPithon/pythonwrapperscript.py", line 110, in <module> 
reallyReallyLongAndUnnecessaryPrefix.data = json.dumps([eval(reallyReallyLongAndUnnecessaryPrefix.argData)]) 
File "C:\Users\ANACON~1\lib\json\__init__.py", line 244, in dumps 
return _default_encoder.encode(obj) 
File "C:\Users\ANACON~1\lib\json\encoder.py", line 207, in encode 
chunks = self.iterencode(o, _one_shot=True) 
File "C:\Users\ANACON~1\lib\json\encoder.py", line 270, in iterencode 
return _iterencode(o, 0) 
File "C:\Users\ANACON~1\lib\json\encoder.py", line 184, in default 
raise TypeError(repr(o) + " is not JSON serializable") 
TypeError: array([[ 0.36534654,  0.31962481,  0.44229946, ...,  0.11513079, 
0.07156331,  0.00286971], [ 0.41534291,  0.41333479,  0.48118995, ...,  0.19203674, 
0.04192771,  0.03679473], [ 0.5188

这个错误是由我的代码中的语法问题引起的吗?我使用 Python 2.7 版本的适用于 Windows 的 Anaconda 4.2.0 平台。

【问题讨论】:

  • python中的mpd函数返回一个二维数组,JSONEncoder默认不支持。在 python 中,执行 import json help(json.encoder) 以查看更多信息。此外,这篇文章似乎与stackoverflow.com/questions/22281059/… 相关
  • 您对使用rPithon 包的决心如何?您是否愿意使用其他一些从 R 调用 Python 函数的方法?
  • 为什么不在命令行中使用 R 的 system()system() 调用 Python 脚本?
  • 非常感谢您的回答。我不知道从 R 调用 Python 函数的 system() 或其他方法。

标签: r rpython


【解决方案1】:

我没有使用过nlmpy 包,因此我不确定您的预期输出是什么。但是,此代码在 R 和 Python 之间成功通信。

有两个文件,

nlmpyInR.R

command ="python"
path2script="path_to_your_pythoncode/nlmpyInPython.py"

nRow <-50 
nCol <-50 
h <- 0.75

# Build up args in a vector
args = c(nRow, nCol, h)

# Add path to script as first arg
allArgs = c(path2script, args)

Routput = system2(command, args=allArgs, stdout=TRUE)
#The command would be python nlmpyInPython.py 50 50 0.75

print(paste("The Output is:\n", Routput))

nlmpyInPython.py

import sys
import nlmpy 
#Getting the arguments from the command line call
nRow = sys.argv[1]
nCol = sys.argv[2]
h = sys.argv[3]

nlm = nlmpy.mpd(nRow, nCol, h) 
pyhtonOutput = nlmpy.exportASCIIGrid("raster.asc", nlm)
#Whatever you print will get stored in the R's output variable. 
print pyhtonOutput

【讨论】:

  • 非常感谢您的回复!从 R 运行代码时出现错误消息(“nlmpylnPython.py”中的代码在 Python 中有效):running command '"python" C:/nlmpyInPython.py 50 50 0.75' had status [1] "Traceback (most recent call last):" [2] " File \"C:/nlmpyInPython.py\", line 14, in &lt;module&gt;" [3] " nlm = nlmpy.mpd(nRow, nCol, h) " [4] " File \"C:\\Users\\ANACON~1\\lib\\site-packages\\nlmpy\\nlmpy.py\", line 523, in mpd"
  • 错误信息的其余部分是[5] " mask = np.ones((nRow, nCol)) " [6] " File \"C:\\Users\\ANACON~1\\lib\\site-packages\\numpy\\core\\numeric.py\", line 190, in ones" [7] " a = empty(shape, dtype, order)" [8] "TypeError: an integer is required" attr(,"status") [1] 1
  • @Nell 我在我的 Windows 系统上运行过,它运行良好。 python 调用似乎有点可疑。为什么是'"python" C:/nlmpyInPython.py 50 50 0.75'?而不应该是python C:/nlmpyInPython.py 50 50 0.75?看起来数字 50 50 0.75 将作为字符串。
  • 我通过在 R 中使用 class(nRow) 检查了 nRow、nCol 和 h 是数字。所有这些参数都是数字。我还通过运行command="C:/Users/Anaconda2/python.exe" 而不是command="python" 测试了Python 路径。我又收到了同样的错误信息。
  • 你能从命令行运行python C:/nlmpyInPython.py 50 50 0.75并检查它是否运行正常吗?
【解决方案2】:

您遇到错误的原因由 “不是 JSON 可序列化的”行。您的 R 代码调用 mpd 具有某些参数的函数,并且该函数本身将 正确执行。然后 rPithon 库将尝试发送 将函数的值返回给 R,为此它将尝试 创建一个JSON 对象 描述返回值。

这适用于整数、浮点值、数组等, 但并不是每一种 Python 对象都可以转换成这样的 JSON 表示。并且因为 rPithon 不能转换返回值 的mpd 这样,就会产生错误。

您仍然可以使用 rPithon 调用 mpd 函数。以下 代码创建一个新的 Python 函数,它执行两个步骤:首先 它使用指定的参数调用mpd 函数,然后它 将结果导出到文件,文件名也是一个参数。 使用 rPithon,然后从 R 调用新函数。因为myFunction 不返回任何内容,所以以 JSON 格式表示返回值不会有问题。

library("rPithon")

pythonCode = paste("import nlmpy.nlmpy as nlmpy",
                   "",
                   "def myFunction(nRow, nCol, h, fileName):",
                   "    nlm = nlmpy.mpd(nRow, nCol, h)",
                   "    nlmpy.exportASCIIGrid(fileName, nlm)", 
                   sep = "\n")
pithon.exec(pythonCode)

nRow <- 50 
nCol <- 50 
h <- 0.75 

pithon.call("myFunction", nRow, nCol, h, "outputraster.asc")

在这里,Python 代码定义为 R 字符串,并使用 pithon.exec。您还可以将该 Python 代码放在单独的文件中 并使用pithon.load 处理代码,以便myFunction 功能已知。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2022-01-02
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 2015-08-02
    相关资源
    最近更新 更多