你在使用哪种编程语言?快来投票,亲手选出你心目中的编程语言之王 了解详情
写点什么

R 和 Python 可以兼得吗?

2021 年 6 月 26 日

R和Python可以兼得吗?

本文最初发布于 towards data science 网站,经原作者授权由 InfoQ 中文站翻译并分享。


R 和 Python 有很多相似之处,也有很多不同之处。两种语言的数据结构的大多数基础概念都非常相似,并且现在这两种语言都有许多数据科学包可用。


但 R 的设计在我看来是“数据第一,应用第二”,而 Python 从一开始就给人感觉更多是应用程序开发驱动的。例如,纯粹从语法和环境管理的角度来看,Javascript 程序员上手 Python 的速度要比上手 R 的速度快一些。


最近,我在工作中用到 R 和 Python 的次数越来越多,并且遇到了想要同时使用两者的情况。出现这种情况的原因有很多,但最常见的一个场景是你正在用 R 构建某些东西,同时需要自己或其他人之前用 Python 编写的功能。当然,你可以用 R 重写它,但这不是很 DRY 吗?


R 中的 reticulate 这个包让你可以在 R 会话中执行 Python 代码。它实际上已经出来几年了,并且一直在不断改进,所以我想写一个关于它具体用法的简短教程。


如果你是 R 的开发者,要启动和运行 reticulate 需要你了解一些 Python 的运行机制—以及它管理环境的典型做法—所以本教程可以帮助你更快地完成设置,这样就不用你自己去费劲研究了。

R 和 Python 中的环境


任何编程项目都运行在一个环境中,它在这个环境里存储和访问自己在执行过程中需要或创建的所有东西。在 R 中,所有项目都可以使用一个通用的全局环境,在这个环境里可以访问 R 基础语言和所有已安装的包。从这个意义上说,R 中的所有项目通常都运行在相同的公共核心环境中。


换一种方式来看待这个景象,你可以想象你家中所有成员的 iPhone 都共享同一个充电站;他们必须离开自己的房间给手机充电;如果他们出售自己的 iPhone,买家需要自己解决充电问题。


但在 Python 中,每个项目通常都设置为完全自包含的—也就是说有自己的环境、自己的 Python 基础副本和它需要执行的所有模块的独立副本。你可以把这种景象想象成每个人在他们的房间里都有自己的 iPhone 充电器;他们不必走到外面找到统一的充电站来充电;如果他们出售手机,也会附上手机自己的充电器。


Python 的这种模式在安装过程和磁盘/内存资源消耗方面开销更大,但它能让开发者以最少的配置更轻松地在不同人之间转移项目。不难看出,它是直接从软件开发思维中发展出来的,这就是为什么我认为 Python 更像是“应用程序驱动的”。


这里我应该提一下,对于这两种语言的大多数日常用户来说,我所描述的是“典型的”场景。这些模式不是完全不变的,而且如果你知道该怎么做的话,在两种语言中都可以使用两种类型的项目流程。我们还看到 R 语言最近在朝着 Python 风格的环境管理模型迈进——例如 renv 包。


下面是我画的一个小草图,它以简单的方式展示 R 和 Python 中常见环境机制之间的区别。



R 和 Python 中的典型环境工作流


现在,如果你想让 Python 与 R 对话,前者仍然需要找到它自己的环境—你不能告诉它,让它去访问 R 的全局环境。这就像是让一个只会说英语的美国人去找一个只会说中文的中国人问路。


所以,要让 Python 在你的 R 项目中跑起来,你需要做两件事:


  1. 在 R 项目中设置一个 Python 环境,让 Python 可以认出自己的路。

  2. 用于翻译 Python 代码以使其在 R 中工作的 reticulate 包。

设置 Python 环境


从现在开始我会使用一个简单的例子来做说明。


假设我在 RStudio 中有一个 R 项目,它需要使用我用 Python 编写的函数。所以这里有一个简单的函数,我将它保存在我的 R 项目目录 test_python 中的一个名为 light_years.py 的 Python 脚本中(是的,RStudio 允许你创建 Python 脚本!)。


这个函数接收公里或英里为单位的距离作为输入,并计算以光速行进这段距离需要多少年。换句话说,以光年为单位的距离是多少。


from scipy.constants import cdef light_years(dist, unit = "km"):        c_per_year = c * 60 * 60 * 24 * 365.25        if unit == "km":            dist_meters = dist * 1000            elif unit == "mi":              dist_meters = dist * 1.60934 * 1000        else:              sys.exit("Cannot use that unit!")                    return dist_meters/c_per_year
复制代码


我在这里使用了一个非常简单的函数示例,以免让这篇文章太过冗长。所以它有点不切实际,也有点蠢,因为我导入整个 scipy 包只是为了获取一个常量的值,但希望它能帮助你领会我的意思。


现在正像我们上面所讨论的,我们需要为这段代码提供一个环境。它需要:


  1. 要使用的 Python 版本

  2. 访问 scipy 包,从而可以获得常数 c=光速


为你的 R 项目设置一个 Python 环境并不难。鉴于项目环境在 Python 中的重要性,市面上存在许多易用的环境管理工具。


我最喜欢的是 Anaconda。它有两个版本可用。完整版包含环境可能需要的所有一大堆东西,包括所有最常用的 Python 模块。然后是 Miniconda,它占用的磁盘空间少很多,更适合条件有限的 Python 用户。


你可以在此处https://docs.conda.io/en/latest/miniconda.html获取适用于你操作系统的 Miniconda。请为要使用的 Python 版本下载对应的 Conda。


安装完 Conda 后,如果你使用的是 macOS 或 Linux,通常会使用命令行来设置环境。只需转到终端中你的 R 项目目录(在我的例子中是 test_python)并使用以下命令:


conda create --name test_python
复制代码


就这么简单,你现在已经创建了一个 python 环境。我通常将我的环境命名为与项目文件夹相同的名称,以免将来混淆。


现在你需要告诉 Conda,让它为这个项目使用这个环境。当你仍在命令行的 test_python 目录中时,使用以下命令:


conda activate test_python
复制代码


现在你已将此项目链接到了 Python 环境,并且其中有 Python 基础的一个副本供你的代码运行使用。


最后,我们的函数需要 scipy 包,所以我们需要把它放在环境中。只需在激活的项目文件夹中输入以下内容即可:


conda install scipy
复制代码


然后,Conda 会将 scipy 及它认为可能需要的所有依赖项安装到你的活动环境中,你就可以开始使用了——可以这么说,就像 scipy 一样简单。


稍后你需要告诉 R,在这个环境中在哪里可以找到 Python。用这条命令可以获得所有环境的列表以及安装环境的路径:


conda info --envs
复制代码


例如,这能告诉我,我的环境安装在/Users/keithmcnulty/opt/miniconda3/envs/test_python。我总能在 bin 子目录中找到 Python 可执行文件——所以我的项目的 Python 可执行文件的完整路径是/Users/keithmcnulty/opt/miniconda3/envs/test_python/bin/python3,因为我使用的是 Python 3。我们需要告诉 R 的就是这些,这样它就知道在哪里可以找到 Python 环境了。

在 R 中运行你的 Python 函数


现在,无论你是像我一样用 Conda 设置了 Python 环境,还是使用了 virtualenv,你都已经完成了最艰巨的部分。剩下的操作很简单,因为 reticulate 会接手。


首先,当 R 加载项目时,你需要告诉 R,在正确的环境中在哪里可以找到 Python 可执行文件。为此,请启动一个空文本文件并添加以下内容,将我的路径替换为与你创建的项目环境中的 Python 可执行文件匹配的路径。


Sys.setenv(RETICULATE_PYTHON = "/Users/keithmcnulty/opt/miniconda3/envs/test_python/bin/python3")
复制代码


现在将这个文本文件保存在你的项目目录中,名称为.Renv。这是一个隐藏文件,每当你在 RStudio 中启动项目时,R 都会执行该文件。所以现在关闭 RStudio 并在打开 test_python 项目的同时重新启动它,它现在将指向 Python 环境。


如果你还没有安装 reticulate R 包,你应该在这个时候安装。安装后,你可以在终端中尝试一些测试,看看是否一切正常。


首先,你可以测试 R 是否知道 Python 在哪里。reticulate::py_available()应该返回“TRUE”。你还可以测试项目是否安装了你需要的 Python 模块:reticulate::py_module_available("scipy")应返回“TRUE”。假设一切正常,你已准备好将你的函数引入 R 了。


你可以使用简单的一条命令来获取 Python 脚本:


reticulate::source_python("light_years.py")
复制代码


现在你可以将 light_years()函数用作 R 函数。让我们看看以光速行驶一千万英里需要多少年:


> light_years(1000000000000000, "mi")[1] 170.1074
复制代码


很好!显然,这是一个非常简单的示例,但它确实告诉了你关于如何将 Python 代码集成到 R 脚本中的所有信息。你现在可以自由引入目前仅支持 Python 的各种功能或包,并让它们在 R 中工作,这非常令人兴奋。


如果你想查看一些高级示例,进一步了解如何使用 reticulate 将 Python 和 R 结合在一起使用,请查看我最近的几篇文章:


在同一项目中无缝切换R和Python的五种方法https://towardsdatascience.com/five-ways-to-work-seamlessly-between-r-and-python-in-the-same-project-bf173e35fdef


生成参数化Powerpoint文档https://towardsdatascience.com/generating-parameterized-powerpoint-documents-in-python-and-r-333368479038


在R中运行XGBoosthttps://towardsdatascience.com/how-to-run-python-ml-algorithms-easily-in-r-7e3b0f7c7aee

作者介绍


一开始我是一名纯数学家,然后我成为了心理咨询师和数据科学家。我很喜欢将所有这些学科的严谨思想应用在复杂的人性问题上。我也是一位编码极客,还是日本 RPG 的忠实粉丝。可以在LinkedInTwitter上找到我。还可以查看我在 drkeithmcnulty.com 上的博客或我即将发布的关于人类分析的教科书


原文链接:


https://towardsdatascience.com/why-choose-between-r-and-python-b12bf409d0d0

2021 年 6 月 26 日 10:001820
用户头像
刘燕 InfoQ记者

发布了 636 篇内容, 共 199.6 次阅读, 收获喜欢 1224 次。

关注

评论

发布
暂无评论
发现更多内容

架构师训练营第一期——第三周作业

tao

第三周作业

熊桂平

极客大学架构师训练营

Week 3 作业 02

Croesus

架构训练营 - 第3周课后作业 - 学习总结

Pudding

第三周总结

积极&丧

极客大学架构师训练营

架构师训练营第一期——第三周总结

tao

第3周

paul

第三周作业 (作业二)

Geek_83908e

极客大学架构师训练营

架构师训练营 - 第 3 周课后作业(1 期)

Pudding

第二周作业

Kenny

架构师训练营第 1 期第三周课后练习题

郑凯元

极客大学架构师训练营

Week 3 學習總結 - Design patterns

Christy LAW

架構師 設計模式 Design Patterns

链表转换为二叉排序树、反应式编程 RxSwift和RxCocoa 、区块链hyperledger环境搭建、环境架构、John 易筋 ARTS 打卡 Week 20

John(易筋)

响应式编程 ARTS 打卡计划 hyperledger 链表转为二叉排序树 chmod

第三周作业

Kenny

架构师训练营第三周命题作业

一马行千里

极客大学架构师训练营 命题作业

第三周

等燕归

架构师训练营 - 第三周作业

咖啡

【架构师训练营第 1 期 03 周】 学习总结

Bear

极客大学架构师训练营

Week 3 作業一 : Design Patterns

Christy LAW

Java 架構師 設計模式 Design Patterns

架构师训练营第 1 期第三周学习总结

郑凯元

极客大学架构师训练营

极客大学-第三周作业

Black Eyed Peter

极客大学架构师训练营

第三周 代码重构 学习总结

应鹏

极客大学架构师训练营

Week_03 作业

golangboy

第三周课后练习 - 作业 1

致星海

第三周 代码重构 学习笔记

应鹏

学习 极客大学架构师训练营

第三周 学习总结

mm马

极客大学架构师训练营

架构师训练营第 1 期 02 周 总结

Geek_a01290

极客大学架构师训练营

代码重构

ABS

第三周作业(作业一)

Geek_83908e

极客大学架构师训练营

架构师训练营Week03作业

IT老兵重开始

极客大学架构师训练营

架构师训练营第 1 期 02 周 作业

Geek_a01290

极客大学架构师训练营

PingCAP DevCon 现场直播

PingCAP DevCon 现场直播

R和Python可以兼得吗?-InfoQ