从R调用Python
概述
这个网状的包提供了一个R接口Python模块、类和函数。例如,此代码导入Python操作系统
模块并调用其中的一些函数它:
图书馆(网状)
操作系统<- 进口(“操作系统”)
操作系统$列表目录(".")
[1] “.git”“.gitignore”“.Rbuildignore”“.RData”[5] “.Rhistory”“.Rproj.user”“.travis.yml”“appveyor.yml”[9] “DESCRIPTION”“docs”“external”“index.html”[13] “index.Rmd”“inst”“发布”“LICENSE”“[17] “man”“NAMESPACE”“NEWS.md”“pkgdown”[21]“R”“README.md”“reticulate.Rproj”“src”[25]“测试”“想定案例”
Python模块和类中的函数和其他数据可以是通过访问$
操作符(类似于与R列表、环境或引用类交互)。
这个网状的包与所有Python版本>=2.7。与NumPy集成是可选的需要NumPy>=1.6。
Python版本
默认情况下,reticulate使用您的路径
(即Sys.which(“python”)
). 这个use_python()
函数允许您指定备用版本,例如:
图书馆(网状)
使用python(“/usr/local/bin/python”)
这个use_virtualenv()
和use_condaenv()
函数使您能够在virtual或conda中指定Python的版本环境,例如:
请参阅上的文章Python版本配置了解更多详细信息。
Python包
您可以使用标准shell安装任何必需的Python包工具,如管道
和康达
。或者,reticulate包含一组用于管理和安装的功能virtualenvs和Conda环境中的包。请参阅上的文章正在安装Python包了解更多详细信息。
类型转换
调用Python时,R数据类型自动转换为它们的等效Python类型。当值从Python返回到R时它们被转换回R类型。类型转换如下:
单元素向量 |
标量 |
1 ,1升 ,真的 ,“foo” |
多元素向量 |
列表 |
c(1.0、2.0、3.0) ,c(1升、2升、3升) |
多种类型列表 |
薄纱 |
列表(1L,TRUE,“foo”) |
命名列表 |
Dict公司 |
列表(a=1L,b=2.0) ,dict(x=x数据) |
矩阵/阵列 |
数字日历 |
矩阵(c(1,2,3,4),nrow=2,ncol=2) |
数据帧 |
熊猫数据帧 |
数据帧(x=c(1,2,3),y=c(“a”、“b”、“c”)) |
功能 |
Python函数 |
函数(x)x+1 |
原始 |
Python字节数组 |
原始(c(1:10)) |
空、真、假 |
无、正确、错误 |
无效的 ,真的 ,错误的 |
如果返回自定义类的Python对象,则返回R引用返回到该对象。您可以调用方法和访问属性就像它是R引用类的实例一样。
导入模块
这个导入()
函数可用于导入任何Python模块。例如:
difflib<- 进口(“difflib”)
difflib$ndiff公司(foo,bar)
文件cmp<- 进口(“文件cmp”)
文件cmp$化学机械抛光(目录1,目录2)
这个import_main()
和import_builtins()
函数使您可以访问执行代码的主模块默认值和内置Python函数的集合。对于例子:
主要的<- import_main(导入_主)()
内置<- 导入内置项()
内置$打印(“foo”)
如果您执行了Python代码,那么主模块通常很有用并希望访问其结果(请参见有关更多详细信息,请参阅下面的部分)。
寻找脚本
这个source_python()
函数将源代码为Python脚本并使其创建的对象在R环境中可用(通过默认调用环境)。例如,考虑以下内容Python脚本:
我们使用source_python()
函数,然后可以调用添加()
直接来自R的功能:
源python('添加.py')
添加(5,10)
[1] 15
正在执行代码
您可以使用副本文件(_R)
和py_运行_字符串
功能。你然后可以访问使用第页
对象由reticulate出口:
图书馆(网状)
py_运行文件(“script.py”)
py_运行_字符串(“x=10”)
#通过“py”对象访问python主模块
第页$x个
对象转换
默认情况下,当Python对象返回到R时,它们将被转换对应的R型。然而,如果您愿意进行转换默认情况下,从Python到R显式并处理本机Pythons对象你可以通过convert=假
到进口
功能。在这种情况下,Python到R的转换将被禁用模块返回自进口
。例如:
#导入numpy并指定无自动Python到R转换
净现值<- 进口(“numpy”,转换= 错误的)
#使用NumPy进行一些数组操作
一<-净现值$阵列(c(c)(1:4))
总和<-一$累加()
#在末尾显式转换为R
py_to_r(总和)
如上所示,如果您需要在结束时访问R对象您可以调用py_to_r()
功能明确地。
获取帮助
您可以使用py_help()
功能。例如:
操作系统<- 进口(“操作系统”)
py_help(_H)(操作系统$chdir)
列表、元组和字典
R类型到Python类型的自动转换在大多数情况下,但有时您需要在R上更明确side提供Python所需的类型。
例如,如果Python API需要一个列表,并且您传递了一个元素R向量,它将被转换为Python标量。克服这只需使用R列表
函数明确:
类似地,Python API可能需要元组
相当地而不是列表。在这种情况下,您可以使用元组()
功能:
R命名列表被转换为Python字典,但您可以还使用dict()
功能:
字典(foo公司= “酒吧”,索引= 42L(左))
如果需要传递使用更复杂的对象(相对于字符串)作为其键。
数字类型和索引
R和Python有不同的默认数字类型。如果你写42
在R中,它被视为浮点数,而42
在Python中被视为整数。
这意味着当Python API需要整数时,您需要一定要使用L(左)
后缀在R中。例如,如果foo公司
函数需要一个整数作为其指数
你会这样做:
Python集合使用基于0的索引进行寻址,而不是从R中您可能熟悉的基于1的指数。为了解决您将在R中写入数组的第一项:
然而,如果您通过网状结构调用Python中的方法取一个索引,你可以写下它来处理第一项:
请注意基于0的索引以及L(左)
到指示t该值是一个整数。
阵列
R矩阵和数组自动转换为数字Py数组。
从R转换为NumPy时,直接映射NumPy数组到R数组的底层内存(不进行复制)。在这种情况下,NumPy数组使用兼容的基于列的内存布局使用R(即Fortran样式而不是C样式)。从转换时NumPy到R,R接收NumPy数组的按列排序的副本。
您还可以使用np_array()
功能。例如,如果您需要使用C而不是Fortran样式创建NumPy数组内存中布局(在面向行的计算中实现更高的性能)或者如果您想更多地控制NumPy数组的数据类型明确地。以下是一些示例用法np_array()
:
一<- np_阵列(c(c)(1:8),数据类型= “浮点16”)
一<- np_阵列(c(c)(1:8),订单= “C”)
关于使用不同内存顺序的数组的推理可以是很棘手。这个R和Python中的数组文章提供了其他详细信息。
另外,请记住,在调用NumPy方法数组索引时基于0而不是1,并且需要L(左)
后缀到表示它们是整数。
数据帧
R数据帧可以自动转换为熊猫数据帧。默认情况下,使用控制R数组的相同规则转换列NumPy数组转换,但提供了几个扩展:
系数 |
分类变量 |
POSIXt公司 |
具有数据类型的NumPy数组=日期时间64[ns] |
如果R数据帧具有行名称,则生成的Pandas DataFrame将使用这些行名称重新标识(反之亦然)。特殊也可用于日期时间索引
相关使用Pandas DataFrame;然而,因为R只支持字符行名称的向量首先转换为字符。
使用Pandas可为null的数据类型
Pandas对可为null的数据类型有实验性的支持。那些数据类型具有对缺失值的内置支持,由pd编号
使用它们可以更好地表示R纳
值。
用户可以选择使用Pandas可为null的数据类型,而不是numpy通过设置网状.pandas_use_nullable_dypes
到真的
。例如:
数据流<- 数据帧(
整数= c(c)(纳,1:4),
num个= c(c)(纳,rnorm公司(4)),
lgl公司= c(c)(纳,代表(c(c)(真的,错误的),2)),
字符串= c(c)(纳,个字母[1:4])
)
选项(网状.pandas_use_nullable_data_types= 真的)
收件人(_to)(df)
#>int num lgl字符串
#>0<NA><NA><NA><NA>
#>1 1-0.697855 True真
#>2 2-0.253042假b
#>3 3 0.385421真c
#>4 4 0.519933假d
稀疏矩阵
稀疏矩阵由创建矩阵R包可以转换Scipy公司CSC矩阵反之亦然。当您想将稀疏矩阵传递给接受Scipy CSC矩阵的Python函数利用这种格式,例如高效的列切片和快速矩阵向量乘积。
例如,我们首先使用矩阵::稀疏矩阵()
:
库(矩阵)N<-5dgc_矩阵<-稀疏矩阵(i=样品(N,N),j=样品(N,N),x=运行(N),dims=c(N,N))
稀疏矩阵如下所示:
>dgc矩阵“dgCMatrix”类的5 x 5稀疏矩阵[1,] 0.2264952 . . . . [2,] . . . . 0.3927282[3,] . . . 0.9215908 . [4,] . . 0.01777771 . . [5,] . 0.05885743 . . .
让我们使用将其转换为Scipy CSC矩阵r_to_py()
:
>csc矩阵<-r-to_py(x)>csc矩阵(0, 0) 0.226495201467(4, 1) 0.0588574311696(3, 2) 0.0177777127828(2, 3) 0.921590822982(1, 4) 0.392728160601
请注意,右侧包含矩阵,而左侧表示它们在矩阵。
我们还可以使用py_to_r()
将CSC矩阵转换回到矩阵::dgC矩阵
然后可以在与原始稀疏矩阵相同的R中易于操作我们之前使用创建的矩阵::稀疏矩阵()
:
>py_to_r(csc矩阵)“dgCMatrix”类的5 x 5稀疏矩阵[1,] 0.2264952 . . . . [2,] . . . . 0.3927282[3,] . . . 0.9215908 . [4,] . . 0.01777771 . . [5,] . 0.05885743 . . .
带上下文
R具有
泛型函数可用于与Python上下文管理器对象具有
关键字进行相同操作)。例如:
第页<- 导入内置项()
具有(第页$打开(“output.txt”,“w”)%作为%文件{
文件$写(“你好!”)
})
此示例打开一个文件并确保其自动关闭位于with块的末尾。注意使用%作为%
运算符对上下文管理器创建的对象进行别名。
遍历器
如果Python API返回迭代器或生成器,则可以进行交互使用迭代()
功能。这个迭代()
函数可用于将R函数应用于迭代器生成的每个项:
如果不将函数传递给迭代
结果将收集到R矢量中:
请注意遍历器
将耗尽其价值通过迭代()
:
一<- 迭代(iter)#结果不为空
b条<- 迭代(iter)#结果为空,因为项目已被清空
元素级迭代
您还可以使用iter_next()
功能。例如:
虽然(真的) {
项目<- iter_next(_N)(iter)
如果(is.完整(项目)
打破
}
默认情况下iter_next()
将返回无效的
当迭代完成,但您可以提供自定义完整的
它将被返回。对于例子:
虽然(真的) {
项目<- iter_next(_N)(iter、,已完成= 纳)
如果(国际标准编号(项目)
打破
}
注意,Python中的一些迭代器/生成器是无限的。在那里面case调用方将需要自定义逻辑来确定何时终止循环。
发电机
蟒蛇发电机是实现Python迭代器协议的函数。类似地网状的发电机()
函数使您能够创建来自R函数的Python迭代器。
在Python中,生成器使用产量
关键字。在R中,值只是从函数返回的。一个好处的产量
关键字是启用连续迭代以使用以前迭代的状态。在R中,这可以是通过返回一个通过改变其封闭环境的函数来完成<<-运算符。例如:
#定义生成器函数
序列生成器<-功能(开始){
价值<-开始
功能() {
价值<<-价值+ 1
价值
}
}
#将函数转换为python迭代器
国际单位<- py_致畸剂(序列生成器(10))
如果要指示迭代的结束,请返回无效的
从函数:
序列生成器<-功能(开始){
价值<-开始
功能() {
价值<<-价值+ 1
如果(值< 100)
价值
其他的
无效的
}
}
请注意,您可以更改指示迭代使用完整的
参数(例如py_iterator(函数,已完成=NA)
).
功能
签名
默认情况下,R函数通过泛型转换为Python签名(函数(…)
),其中既没有关键字参数或参数的默认值。
例如,下面我们应用r_to_py()
到R函数然后我们使用检查Python模块以获取转换后的函数的参数规范。您可以看到包装函数的签名看起来与原始R函数的签名。
>检查<- 进口(“检查”)
>已转换的func<- 收件人(_to)(功能(a),b条= 1.5) {})
>检查$获取argspec(已转换为func)
ArgSpec标准(参数=[],变量='参数',关键字=“夸格斯”,默认值=无)
此默认转换通常工作良好,但有些Python图书馆严格检查用户的函数签名提供了回调。在这些情况下,通用函数(…)
签名将无法通过此检查。
对于这些情况,您可以使用py_func()
包裹R函数,以便包装的函数具有与原始R函数的参数,例如一个参数一
没有默认值和其他参数b条
使用默认值值1.5。
>包装func<- 副本(_F)(功能(a),b条= 1.5) {})
>检查$获取argspec(wrapped_func)
ArgSpec标准(参数=[“a”,“b”],变量=无,关键字=无,默认值=(1.5,))
注意,R函数的签名不能包含深奥的Python不兼容的构造。例如,我们不能有R函数带有类似签名的函数(a=1,b)
自Python以来函数要求没有默认值的参数出现在具有默认值的参数。
背景线程
在某些情况下,Python库会调用Python背景线程。因为R代码必须在主线程上运行,所以这不会默认情况下,当您将R函数作为回调传递时,它将起作用。
要解决此问题,可以使用py_main_thread_func()
,它将为您的R函数提供一个特殊的包装器,以确保它将仅在主线程上调用。
高级
有几个更高级的功能可用主要是在为Python创建高级R接口时库。
Python对象
通常与来自R的Python对象交互涉及使用$
运算符访问函数的任何属性你需要的对象。使用时$
,Python对象是在可能的情况下自动转换为R等价物。这个以下函数使您能够在较低级别(例如,除非显式调用这个py_to_r
功能):
py_has_attr() |
检查对象是否具有指定的属性。 |
py_get_attr() |
获取Python对象的属性。 |
py_set_attr() |
设置Python对象的属性。 |
py_list_attributes() |
列出Python对象的所有属性。 |
py_len() |
Python对象的长度。 |
py_call() |
使用指定的参数调用Python可调用对象。 |
py_to_r() |
将Python对象转换为其R等效对象 |
r_to_py() |
将R对象转换为其Python等效对象 |
泡菜
可以使用py_save_object(保存对象)
和py加载对象
功能:
py_save_object() |
使用pickle将Python对象保存到文件中。 |
py_load_object() |
从文件中加载以前保存的Python对象。 |
配置
以下函数使您能够查询有关当前系统上可用的Python配置。
py_available() |
检查此系统上是否有Python接口。 |
py_numpy_available() |
检查NumPy的R接口是否可用(需要NumPy>= 1.6) |
py模块可用() |
检查此系统上是否有Python模块。 |
py_config() |
获取有关正在使用的Python的位置和版本的信息。 |
输出控制
这些函数使您能够从蟒蛇:
py_capture_output() |
捕获指定表达式的Python输出并将其返回为R字符向量。 |
py_suppress_warnings() |
执行指定的表达式,取消显示Python警告。 |
其他
这些功能提供其他低级别的杂项能力:
py_set_seed() |
设置Python和NumPy随机种子。 |
py_unicode() |
将字符串转换为Python unicode对象。 |
py_str() ,py_repr() |
获取Python对象的字符串表示。 |
py_id() |
获取Python对象的唯一标识符 |
py_is_null_xptr() |
检查Python对象是否为null externalptr。 |
py_validate_xptr() |
检查Python对象是否为空externalptr并抛出如果是,则返回错误。 |
了解更多信息
以下文章涵盖了使用的其他方面网状的: