将Python和R整合进一个数据分析流程

简介:

◆ ◆ 

序言


在Python中调用R或在R中调用Python,为什么是“和”而不是“或”?


在互联网中,关于“R Python”的文章,排名前十的搜索结果中只有2篇讨论了一起使用R和Python的优点,而不是把这两种语言对立起来看。这是可以理解的:这两种语言从一开始都具有非常显著的优缺点。从历史上看,尽管把两者分割开来是因为教育背景:统计学家们倾向用R,而程序员则选择了Python语言。然而,随着数据科学家的增加,这种区别开始变得模糊起来:


数据科学家就是这样一种人:软件工程师中最懂统计学,统计学家中最会编程的人。 -  josh_wills在推特上这样说到。


由于这两种语言各自提供大量独特的库资源,对能够利用这两种语言的相对优势的数据科学家的需求正在不断增长。


◆ ◆ 

Python与R的对比


在以下领域中,Python 比R 更有优势:

  • 网络爬虫和数据抓取:虽然R中的rvest已经简化了网页抓取, Python的beautifulsoup和Scrapy更加成熟,并提供更多的功能。

  • 数据库连接:虽然R有大量的用于连接到数据库的选项, Python的sqlachemy只用了一个程序包就提供了所有的数据库连接功能,并可广泛用于生产环境。


而在以下领域中,R比Python更有优势:

  • 统计分析选项:尽管Python的SciPy和 Pandas以及 statsmodels的组合提供了很大的一套统计分析工具,而R是专门围绕着统计分析应用等创建的,因此提供了更多的相关工具。

  • 交互式图像或控制板:bokeh, plotly和intuitics最近都把Python的图形使用扩展到了Web浏览器,但是举个使用shiny的例子,R中的shiny 控制面板运行速度更快,而且往往需要更少的代码。


此外,由于数据科学团队现在拥有一个比较广泛的技能库,任何应用程序所选择的编程语言都可能用到以前的知识和经验。对于一些应用,特别是原型设计和开发应用,人们使用他们已知的工具则速度会更快。


纯文本 的“Air Gap(网闸)”策略

指在完全断开网络物理连接的基础上,实现合法信息的共享。本文中指用纯文本文件实现两种语言间代码的共享——译者注。


使用纯文本作为两种语言之间的物理隔离,你需要按如下步骤进行。

  1. 从命令行中重构你的R和Python脚本,并接受命令行参数。

  2. 输出共享数据到公共文件格式。

  3. 在一种语言中执行另一种语言,按要求传递参数。


优势:

  • 最简单的方法,通常最快

  • 可以轻松查看中间输出结果

  • 已有常见文件格式,如: CSV , JSON , YAML的解析器


劣势:

  • 需要事先商定一个共同的模式或文件格式

  • 如果流程变长的话,难以管理中间输出结果和路径

  • 如果数据量变大,本地磁盘读写将成为瓶颈


命令行脚本

通过Windows 或Linux终端环境命令行运行R和Python脚本类似。要运行的命令被分解成以下部分:

 

其中

  •  是可执行的命令 (R代码中是 Rscript, Python代码中是Python)

  • 是执行脚本所在的完整或相对文件路径。需要注意的是,如果在路径名中有空格,整个文件路径必须用双引号括起来。

  • 这是空格分隔的参数列表用来解析脚本本身。请注意,这些不能作为字符串传递。


例如,打开一个终端环境并运行R脚本,命令如下:

Rscript path/to/myscript.R arg1 arg2 arg3 


请注意以下问题:

  • 对于Rscript 和Python 命令必须在你所在的路径中执行,否则你需要提供文件的完整路径。

  • 含有空格符的路径名会产生问题,尤其是在Window系统中,因此必须用双引号括起来,这样才被认为是一个单独的文件路径。


R语言中访问命令行参数

上面的例子中,arg1,arg2 和 arg3是用来解析可执行R脚本的参数,可以使用commandArgs函数访问


##myscript.py

#获取命令行参数

myArgs <- commandArgs(trailingOnly = TRUE)  

#myArgs是所有参数的特征向量

print(myArgs) print(class(myArgs)) 


通过设置trailingOnly 为TRUE,myArgs向量中只包含添加到命令行的参数。如果默认设置为FALSE ,myArgs向量中还包含其它参数,比如刚被执行的脚本路径。


Python语言中访问命令行参数

通过下面的命令行执行Python脚本:

python path/to/myscript.py arg1 arg2 arg3


通过在Python脚本中导入sys模块访问arg1, arg2 和arg3参数。 sys模块包含了系统具体的参数和函数,在这里,我们只对 argv的属性感兴趣。这个argv属性是所有被传递到当前正在执行脚本的参数列表。表中的第一个元素是正在被执行的脚本的完整路径。

# myscript.py

import sys 

# 获取命令行参数

my_args = sys.argv 

# my_args 是一个列表,其中的第一个元素是执行的脚本

print(type(my_args))

print(my_args)


如果你只希望保留传递到脚本的参数,你可以使用列表切片来选择除了第一个元素以外的所有参数。


# 使用切片,选择除第一个以外的所有元素

my_args = sys.argv[1:]

 

回顾一下上面的R语言例子,所有的参数需要以字符串的形式传递,因此有必要转换为所期望的数据类型。


将输出结果写入文件

通过中间文件共享R和Python之间的数据有几种选择。通常,对于普通文本文件,CSVs是很好的表格数据格式,而处理可变长字段或许多嵌套数据结构的非结构化数据(或元数据)形式时,JSON 或YAML是最好的数据格式。


这些都是很常见的数据序列化格式,在R和Python中已存在相应的语法解析器。


在R语言中推荐下面的程序包:

  • 对于CSV文件,使用readr

  • 对于JSON文件,使用jsonlite

  • 对于YAML文件,使用yaml


Python中推荐:

  • 对于CSV文件,使用csv

  • 对于JSON文件,使用json

  • 对于YAML文件,使用PyYAML


csv 和json模块是Python标准的库文件,是Python内置模块,而PyYAML需要额外安装程序包。所有的R程序包均需要安装。


◆ ◆ 

总结


R 和Python之间的数据传递可以通过单一传递途径进行:

  • 使用命令行传递参数

  • 使用常见的结构化文本文件传递数据


然而,在某些实例中,需要将文本文件作为中间文件存储在本地,这不仅很麻烦而且还影响性能。接下来,我们将讨论如何在R和Python中直接调用并在内存中输出。

 

命令行执行和执行子进程

为了更好地理解在执行子进程的时候发生了什么,值得重新考虑当命令行运行一个Python 或 R进程中更多的细节。在运行下面的命令时,启动了一个新的 Python 进程执行该脚本。

在执行过程中,任何被输出到标准输出和标准错误流的数据会返回到控制台显示。最常见的实现方式是通过Python中的一个内置函数print()或是 R中的函数 cat()和 print(),它们将给定字符串的写入标准输出流。一旦脚本执行完毕,Python进程随即关闭。


在这种方式下运行命令行脚本是有用的,但如果希望用这个方法执行多个连续却相互独立脚本时,就变得繁琐,并且容易出错。然而,这可能让一个Python或R进程直接去执行另一个类似的命令。这样有好处,即从一个Python父进程启动一个R中的子进程去运行特定的脚本,进而完成分析。一旦R脚本运行完毕,R中子进程的输出不是被传到控制台,而是返回到父进程中。使用这种方法除去了手动单独执行命令行的步骤。


实例

为了说明一个进程的执行是由另一个进程引起的,我们将会用两个简单的例子:一个是Python调用R,另一个是R调用Python。我们人为降低了每个案例中分析结果的重要性,以便把重点放在机器是如何的实现的过程上。

R脚本范例


我们简单的R脚本例子要从命令行获取一系列数字并返回最大值。

 

# max.R

# 获取命令行参数

myArgs <- commandArgs(trailingOnly = TRUE)

# 转换成数字类型

nums = as.numeric(myArgs) 

# cat将把结果写入标准输出流

cat(max(nums))


在Python中执行R脚本

我们需要利用子进程的模块,也就是标准库的一部分,来实现从Python中进行调用。我们将使用函数check_output 来调用 R 脚本,执行命令并存储标准输出的结果。

 

想要在Python中调用R来执行 max.R脚本,首先要建立要运行的命令。在Python中的形式以一个字符串列表表示,其相应的元素如下所示:

['', '', 'arg1' , 'arg2', 'arg3', 'arg4']


下面代码是运行在Python中调用R的一个例子:

# run_max.py

import subprocess

# 定义命令和参数

command = 'Rscript'

path2script = 'path/to your script/max.R' 

# args变量的值是一个列表

args = ['11', '3', '9', '42'] 

#建立子进程命令

cmd = [command, path2script] + args 

# check_output会执行命令并存储结果

x = subprocess.check_output(cmd, universal_newlines=True)

print('The maximum of the numbers is:', x)


参数 universal_newlines=True 告诉 Python 把返回的输出结果解释为文本字符串,并处理 Windows 和 Linux 的换行字符。如果省略了这个,则输出结果会被作为一个字节的字符串返回,同时在进行任何字符串进一步操作之前必须调用x.decode()来解码成文本。


Python 脚本范例

在我们简单的 Python 脚本中,我们将给定的字符串(第一个参数)拆分为基于所提供的字符串模式的多个子字符串 (第二个参数)。然后,结果以每行一个子字符串的形式输出到控制台。


# splitstr.py

import sys

# 获取传入的参数

string = sys.argv[1]

pattern = sys.argv[2]

#执行分割

ans = string.split(pattern)

#把所产生的元素列表合成一个新命令行

# 分割字符串并打印

print('\n'.join(ans))


在R中调用Python

当用R执行子进程时,建议使用 R 的system2函数来执行并获取输出。这是因为内置的系统函数跨平台不兼容,非常难使用。


建立要执行的命令是类似于上面的 Python 例子,然而system2 期望命令根据它的参数被分解开来。此外,这些参数首先必须总是正在执行的脚本的路径。


最后一个困难可能是R脚本路径名称中的空格处理引起的。解决这一问题最简单的方法是为全路径名称加上双引号,然后用单引号封装此字符串,这样,R保留参数本身的双引号。

下面的代码中,给出在R 中执行 Python 脚本的实例。


# run_splitstr.R

command = "python"

#注意在字符串中的单引号和双引号(如果路径名中有空格,这是必须的)

path2script='"path/to your script/splitstr.py"' 

# 设置args成向量

string = "3523462---12413415---4577678---7967956---5456439"

pattern = "---"

args = c(string, pattern)

# 把脚本路径加入,成为第一个arg参数

allArgs = c(path2script, args) 

output = system2(command, args=allArgs, stdout=TRUE)

print(paste("The Substrings are:\n", output))


为了获取标准输出中的特征向量(每个元素一行),stdout=TRUE 必须在system2中具体说明,不然返回的只是退出状态。当stdout=TRUE时,退出状态存储在一个名为“状态”的属性中。

 

总结

通过子进程调用,可以将Python和R整合到一个应用程序中。这允许一个父进程调用另一个进程作为子进程,并获取任何输出到标准输出的结果。


原文发布时间为:2016-05-07

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“BigDataDigest”微信公众号

相关文章
|
4月前
|
数据可视化 大数据 关系型数据库
基于python大数据技术的医疗数据分析与研究
在数字化时代,医疗数据呈爆炸式增长,涵盖患者信息、检查指标、生活方式等。大数据技术助力疾病预测、资源优化与智慧医疗发展,结合Python、MySQL与B/S架构,推动医疗系统高效实现。
|
4月前
|
JSON 算法 API
Python采集淘宝商品评论API接口及JSON数据返回全程指南
Python采集淘宝商品评论API接口及JSON数据返回全程指南
|
4月前
|
数据采集 Web App开发 数据可视化
Python零基础爬取东方财富网股票行情数据指南
东方财富网数据稳定、反爬宽松,适合爬虫入门。本文详解使用Python抓取股票行情数据,涵盖请求发送、HTML解析、动态加载处理、代理IP切换及数据可视化,助你快速掌握金融数据爬取技能。
2617 1
|
4月前
|
数据可视化 关系型数据库 MySQL
【可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
本文详解基于Python的电影TOP250数据可视化大屏开发全流程,涵盖爬虫、数据存储、分析及可视化。使用requests+BeautifulSoup爬取数据,pandas存入MySQL,pyecharts实现柱状图、饼图、词云图、散点图等多种图表,并通过Page组件拖拽布局组合成大屏,支持多种主题切换,附完整源码与视频讲解。
414 4
【可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
|
4月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
576 0
|
4月前
|
JSON API 数据安全/隐私保护
Python采集淘宝拍立淘按图搜索API接口及JSON数据返回全流程指南
通过以上流程,可实现淘宝拍立淘按图搜索的完整调用链路,并获取结构化的JSON商品数据,支撑电商比价、智能推荐等业务场景。
|
5月前
|
数据采集 关系型数据库 MySQL
python爬取数据存入数据库
Python爬虫结合Scrapy与SQLAlchemy,实现高效数据采集并存入MySQL/PostgreSQL/SQLite。通过ORM映射、连接池优化与批量提交,支持百万级数据高速写入,具备良好的可扩展性与稳定性。
|
5月前
|
JSON API 数据安全/隐私保护
Python采集淘宝评论API接口及JSON数据返回全流程指南
Python采集淘宝评论API接口及JSON数据返回全流程指南
|
5月前
|
机器学习/深度学习 文字识别 Java
Python实现PDF图片OCR识别:从原理到实战的全流程解析
本文详解2025年Python实现扫描PDF文本提取的四大OCR方案(Tesseract、EasyOCR、PaddleOCR、OCRmyPDF),涵盖环境配置、图像预处理、核心识别与性能优化,结合财务票据、古籍数字化等实战场景,助力高效构建自动化文档处理系统。
1460 0
|
5月前
|
数据采集 数据可视化 关系型数据库
基于python大数据的电影数据可视化分析系统
电影分析与可视化平台顺应电影产业数字化趋势,整合大数据处理、人工智能与Web技术,实现电影数据的采集、分析与可视化展示。平台支持票房、评分、观众行为等多维度分析,助力行业洞察与决策,同时提供互动界面,增强观众对电影文化的理解。技术上依托Python、MySQL、Flask、HTML等构建,融合数据采集与AI分析,提升电影行业的数据应用能力。

推荐镜像

更多