R调用Python(reticulate包的基本使用)

一.reticulate包的基本使用介绍

以下内容详见:reticulate的文档

1、基础介绍

CRAN已于2018年3月21日收录reticulat包(1.6版本),它包含了用于Python和R之间协同操作的全套工具,在R和Rstudio中均可使用。主要包括:

1)在R中支持多种方式调用Python。包括R Markdown、加载Python脚本、导入Python模块以及在R会话中交互式地使用Python。

2)实现R和Python对象之间的转换(例如R和Python数据框、R矩阵与NumPy数组之间)。

3)灵活绑定到不同版本的Python,包括虚拟环境和Conda环境。

2、操作说明

1)安装并加载reticulate包

# 安装reticulate包
install.packages("reticulate")
# 加载reticulate包
library(reticulate)

2)设定python环境

有三种设定的方法,见: Python Version Configuration

在这里由于我使用的是anaconda3的Python环境,故使用use_condaenv进行指定Python环境

#py_available()#[1] FALSE  #检查您的系统是否安装过Python
use_condaenv("D:/Program Files (x86)/Anaconda3")

py_config()#安装的python版本环境查看,显示anaconda和numpy的详细信息。
py_available()#[1] TRUE   #检查您的系统是否安装过Python
py_module_available("pandas")#检查“pandas”是否安装

3)在R中导入一个python模块

可使用import() 导入任何Python模块并从R中调用它

os <- import("os")
os$getcwd()
os$listdir()#您可以使用os包中的listdir()函数来查看工作目录中的所有文件

numpy <- import("numpy")
y <- array(1:4, c(2, 2))
y
x <- numpy$array(y)
x
numpy$transpose(x)#将数组进行转置
numpy$linalg$eig(x)#求特征根和特征向量

注:可以通过$运算符访问Python模块和类中的函数和其他数据(类似于与R列表,环境或引用类进行交互的方式)

4)交互使用R与Python( Python REPL)

通过使用repl_python()函数,交互地使用R与Python。(相当于在R中创建交互式Python控制台。)

  • 在Python中创建的对象可在R中使用,利用py object获取python里的对象,eg:py$train_data。
  • 在R中创建的对象也可在Python中使用,利用r object获取R里的对象,eg:r.mydata(具体例子见下面)
repl_python()
# 加载“panda”数据集
import pandas as pd
# 载入数据集
train_data=pd.read_csv('iris.txt',header=None)
train_data.columns=['sepal_length','sepal_width','petal_length','petal_width','label']
#print(train_data.head(),train_data.shape,train_data.describe(include = 'all'))
train_data['label']=train_data.label.apply(lambda x: 1 if x=='Iris-setosa' else 0)
# 显示数据集的行列数
train_data.shape
# 随机选取数据集中的行数
train_data.sample(n = 10)
# 回到R
exit

#利用py object获取python里的对象
summary(py$train_data)

#从Python中获取在R中创建的对象
mydata = head(cars, n=15)
repl_python()
import pandas as pd
r.mydata.describe()
pd.isnull(r.mydata.speed)
exit

注意:需要键入“exit”来返回到R会话

5)载入Python脚本

可以使用函数:source_python()获取任何Python脚本,就像使用R脚本一样

source_python("D:/python/R_python/test01.py") 
irisData <- read_Iris("iris.txt")
summary(irisData)


test01.py脚本为:

import pandas as pd

def read_Iris(file):
    train_data = pd.read_csv(file, header=None)
    train_data.columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'label']
    train_data['label'] = train_data.label.apply(lambda x: 1 if x == 'Iris-setosa' else 0)
    return train_data

例2:执行Python文件并调用Python文件中的变量

把上面的Python脚本添加如下代码(或改为它)时:

def add(x, y):
  return(x + y)

result = add(5,10)

R部分:

py_run_file("D:/python/R_python/test01.py") 
py$result  #[1] 15

或者下面这样时:

py_run_string("x=10;y=20")
py$x[1] #[1] 10
py$y[1] #[1] 20

 

6)类型转换

当调用Python时,R数据类型会自动转换为它们等效的Python类型。 当值从Python返回到R时,它们会被转换回R类型。 如果返回自定义类的Python对象,则返回该对象的R引用。类型转换如下:    
              

从R类型到Python类型的自动转换在大多数情况下都能很好地工作,但是偶尔需要在R方面更加明确地提供Python所期望的类型。比如,Python API可能需要元组而不是列表,在这种情况下,可以使用tuple()函数定义。

 

二:进行R调用Python的代码实现

测试R调用Python传递并返回不同数据类型(是上面内容的使用,有些赘余,仅为记录)

Python代码的共同部分:

import numpy as np

R代码的共同部分:

# 加载reticulate包
library(reticulate)

#载入Python脚本
source_python("D:/python/R_python/first_Test.py") 

注:以下所有的运行结果中Python代码的结果在后面

1、传递并返回数值

Python部分:

#在R中,integer :整型;  numeric :数值型 (double)
def add(x, y):
  return x + y

R部分:

x=5.2
y=10.6
result1 <- add(x, y)
cat(x,'+',y,'=',result1,sep = '')#R语言的输出:cat() print() paste() 输入:scan() readline()

运行结果:

5.2+10.6=15.8

 

2、传递并返回字符串

Python部分:

def Hello(s):
    print(s)
    reStr=s+"\nHello R!!"
    return reStr

R部分:

s = 'Hello Python!!'
result2 <- Hello(s)
cat(result2)

运行结果:

Hello Python!!
Hello R!!

Hello Python!!

3、传递并返回一维list数组(Python角度)

Python部分:

def szTest(List):
    print(List)
    #print(type(List))#<class 'list'>
 
    IntegerList = [1, 2, 3]
    return IntegerList

R部分:

#传递一维数组(R的multi-element vector 对应于Python的list)
sz=c(2.0,3.1,4.2,5.3,6.6)
#t=tuple("a", "b", "c")
result3 <- szTest(sz)
cat(result3)

运行结果:

1 2 3

[2.0, 3.1, 4.2, 5.3, 6.6]

4、传递并返回二维numpy数组(Python角度)

Python部分:

def szSecTest(npSzSec):
    print(npSzSec)
    #print(type(npSzSec))  #<class 'numpy.ndarray'>

    IntegerList = [[1, 2, 3], [2, 3, 4]]
    IntegerList =np.array(IntegerList)
    return IntegerList

R部分:

#传递二维数组(R的Matrix/Array 对应于Python的Numpy ndarray)
np_ma=matrix(c(1.1,2.2,3.3,4.4), nrow = 2, ncol = 2)
result4<- szSecTest(np_ma)
cat(result4)
dim(result4)

运行结果:

1 2 2 3 3 4
[1] 2 3

[[1.1 3.3]
 [2.2 4.4]]

5、将R的list传给Python,并返回

Python部分:

def list_Tuple(tuple_in):
    #print(type(tuple_in))#<class 'list'>
    print(tuple_in)

    tuple_in[0] += 2
    tuple_in[1] += 2
    tuple_in[2] += ' add'

    #print(type(tuple_in[3]))  # <class 'list'>
    for i in range(len(tuple_in[3])):
        tuple_in[3][i]+=2

    #print(type(tuple_in[4]))  # <class 'numpy.ndarray'>
    row_ = tuple_in[4].shape[0]
    col_ = tuple_in[4].shape[1]
    x4=np.zeros((row_,col_))
    for i in range(row_):
        for j in range(col_):
            x4[i][j]=tuple_in[4][i][j] +2
            #tuple_in[4][i][j] +=2 # 报错:Error in py_call_impl(callable, dots$args, dots$keywords) : ValueError: assignment destination is read-only

    # 使用.pop()删除最后一个元素
    tuple_in.pop()
    tuple_in.append(x4)
    return tuple_in

R部分:

#传递list(R的List of multiple types对应于Python的Tuple,但测试时发现Python接受时为list类型),感觉其可以当做结构体传递
list_in=list(1L,2.0,'string',c(2.0,3.1,4.2,5.3,6.6),matrix(c(1.1,2.2,3.3,4.4,5.5,6.6), nrow = 2, ncol = 3))
result5<- list_Tuple(list_in)
result5

运行结果:

[[1]]
[1] 3
[[2]]
[1] 4
[[3]]
[1] "string add"
[[4]]
[1] 4.0 5.1 6.2 7.3 8.6
[[5]]
     [,1] [,2] [,3]
[1,]  3.1  5.3  7.5
[2,]  4.2  6.4  8.6


[1, 2.0, 'string', [2.0, 3.1, 4.2, 5.3, 6.6], array([[1.1, 3.3, 5.5],
       [2.2, 4.4, 6.6]])]

也可以交互地使用Python与R,来实现上面这部分,这里就不在记录相关的了。

 

 

 

本文参考的文章:

手把手 | 哇!用R也可以跑Python了

reticulate: R interface to Python

剪不断理还乱的R与Python

 

  • 19
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值