Py学习  »  Python

深入对比数据科学工具箱:Python和R之争

生信宝典 • 4 年前 • 463 次点击  

本文系HarryZhu于2016年的原创文章(作者HarryZhu的FinanceR专栏:https://segmentfault.com/blog...)原文链接:https://segmentfault.com/a/1190000004879349

生信宝典注:python和R是学习数据分析常用技能,作者经比较发现在两者间选择的话,果然还是两把刷子都要,思及此,我们也为python和人工智能学习者推荐几本书并争取到了送书福利,详情还看  包邮送45本豆瓣9.0评分以上Python&AI书籍

概述

在真实的数据科学世界里,我们会有两个极端,一个是业务,一个是工程。偏向业务的数据科学被称为数据分析(Data Analysis),也就是A型数据科学。偏向工程的数据科学被称为数据构建(Data Building),也就是B型数据科学。
从工具上来看,按由业务到工程的顺序,这个两条是:EXCEL >> R >> Python >> Scala
在实际工作中,对于小数据集的简单分析来说,使用EXCEL绝对是最佳选择。当我们需要更多复杂的统计分析和数据处理时,我们就需要转移到 PythonR上。在确定工程实施和大数据集操作时,我们就需要依赖Scala 的静态类型等工程方法构建完整的数据分析系统。
Scala和Excel是两个极端,对于大多数创业公司而言,我们没有足够多的人手来实现专业化的分工,更多情况下,我们会在Python和R上花费更多的时间同时完成数据分析(A型)和数据构建(B型)的工作。而许多人也对 Python和R的交叉使用存在疑惑,所以本文将从实践角度对Python和R中做了一个详细的比较。

应用场景对比

应用Python的场景

  • 网络爬虫/抓取:尽管rvest已经让R的网络爬虫/抓取变得容易,但 Python 的 beautifulsoup 和 Scrapy 更加成熟、功能更强大,结合django-scrapy我们可以很快的构建一个定制化的爬虫管理系统。

  • 连接数据库: R 提供了许多连接数据库的选择,但 Python 只用 sqlachemy 通过ORM的方式,一个包就解决了多种数据库连接的问题,且在生产环境中广泛使用。Python由于支持占位符操作,在拼接SQL语句时也更加方便。

  • 内容管理系统:基于Django,Python可以快速通过ORM建立数据库、后台管理系统,而R  中的 Shiny 的鉴权功能暂时还需要付费使用。

  • API构建:通过Tornado这个标准的网络处理库,Python也可以快速实现轻量级的API,而R则较为复杂。

应用R的场景

  • 统计分析: 尽管 Python 里 Scipy、Pandas、statsmodels 提供了一系列统计工具 ,R 本身是专门为统计分析应用建立的,所以拥有更多此类工具。

  • 互动式图表/面板: 近来 bokeh、plotly、 intuitics 将 Python 的图形功能扩展到了网页浏览器,甚至我们可以用tornado+d3来进一步定制可视化页面,但 R 的 shiny 和 shiny dashboard 速度更快,所需代码更少。


此外,当今数据分析团队拥有许多技能,选择哪种语言实际上基于背景知识和经验。对于一些应用,尤其是原型设计和开发类,工作人员使用已经熟悉的工具会比较快速。

数据流编程对比

接着,我们将通过下面几个方面,对Python和R的数据流编程做出一个详细的对比。

参数传递
数据读取
基本数据结构对照
矩阵转化
矩阵计算
数据操作

参数传递

Python/R都可以通过命令行的方式和其他语言做交互,通过命令行而不是直接调用某个类或方法可以更好地降低耦合性,在提高团队协作的效率。

参数传递PythonR
命令行输入Python path/to/myscript.py arg1 arg2 arg3Rscript path/to/myscript.R arg1 arg2 arg3
脚本识别import sys my_args = sys.argvmyArgs


数据传输与解析

对于数据传输与解析,我们首推的格式是csv,因为一方面,csv格式的读写解析都可以通过 Python 和 R 的原生函数完成,不需要再安装其他包。另一方面,csv格式可以很快的转化为data frame格式,而data frame格式是数据流分析的核心。
不过,实际情况中,我们需要传输一些非结构化的数据,这时候就必须用到 JSNO 或者 YAML。

数据传输与解析PythonR
CSV(原生)csvread.csv
CSV(优化)pandas.read_csv("nba_2013.csv")data.table::fread("nba_2013.csv")
JSONjson(原生)jsonlite
YAMLPyYAMLyaml


基本数据结构

由于是从科学计算的角度出发,R 中的数据结构非常的简单,主要包括 向量(一维)、多维数组(二维时为矩阵)、列表(非结构化数据)、数据框(结构化数据)。而Python则包含更丰富的数据结构来实现数据更精准的访问和内存控制,多维数组(可读写、有序)、元组(只读、有序)、集合(唯一、无序)、字典(Key-Value)等等。

基本数据结构PythonR
数组list:[1,'a']:array:array(c(1,"a"),2)
Key-Value(非结构化数据)字典:["a":1]lists
数据框(结构化数据)dataframedata.frame


Python dict 操作:dict[“key”] 或者 dict.get(“key”,”default_return”)
R list 操作: list[“key”] 或者 list$key

R 中数据结构转化(plyr)listdata framearray
listllply()ldply()laply()
data framedlply()ddply()daply()
arrayalply()adply()aaply()


MapReduce

PythonR
mapMap
reduceReduce
filterfilter


矩阵操作

实际上,Python(numpy)和R中的矩阵都是通过一个多维数组(ndarray)实现的。

矩阵转化PyhtonR
维度data.shapedim(data)
转为向量data.flatten(1)as.vector(data)
转为矩阵np.array([[1,2,3],[3,2,1]])matrix(c(1,2,3,3,2,1),nrow=2,byrow=T)
转置data.Tt(data)
矩阵变形data.reshape(1,np.prod(data.shape))matrix(data,ncol=nrow(data)*ncol(data))
矩阵按行拼接np.r_[A,B]rbind(A,B)
矩阵按列拼接np.c_[A,B]cbind(A,B)


矩阵计算PyhtonR
矩阵乘法np.dot(A,B)A %*% B
矩阵幂指np.power(A,3)A^3
全零矩阵np.zeros((3,3))matrix(0,nrow=3,ncol=3)
矩阵求逆np.linalg.inv(A)solve(A)
协方差np.cov(A,B)cov(A,B)
特征值np.linalg.eig(A)[0]eigen(A)$values
特征向量np.linalg.eig(A)[1]eigen(A)$vectors


数据框操作

参考 R 中的data frame结构,Python的Pandas包也实现了类似的data frame 数据结构。现在,为了加强数据框的操作,R中更是演进出了data table格式(简称dt),这种格式以dt[where,select,group by] 的形式支持类似SQL的语法。

数据框操作PythonR
按Factor的Select操作df[['a', 'c']]dt[,.(a,c),]
按Index的Select操作df.iloc[:,1:2]dt[,1:2,with=FALSE]
按Index的Filter操作df[1:2]dt[1:2]
groupby分组操作df.groupby(['a','b'])[['c','d']].mean()aggregate(x=dt[, c("v1", "v2")], by=list(mydt2$by1, mydt2$by2), FUN = mean)
%in% 匹配操作 返回T/Fpd.Series(np.arange(5),dtype=np.float32).isin([2, 4])0:4 %in% c(2,4)
match 匹配操作 返回Indexpd.Series(pd.match(pd.Series(np.arange(5),dtype=np.float32),[2,4],np.nan))match(0:4, c(2,4))
tapplydf.pivot_table(values='a', columns='c', aggfunc=np.max)tapply(dt$a,dt$c,max)#其中dt$a是numeric,dt$c是nominal
查询操作df[df.a <= df.b]dt[ a<=b ]
with操作pd.DataFrame({'a': np.random.randn(10), 'b': np.random.randn(10)}).eval('a + b')with(dt,a + b)
plyr操作df.groupby(['month','week']).agg([np.mean, np.std])ddply(dt, .(month, week), summarize,mean = round(mean(x), 2),sd = round(sd(x), 2))
多维数组融合pd.DataFrame([tuple(list(x)+[val]) for x, val in np.ndenumerate(np.array(list(range(1,24))+[np.NAN]).reshape(2,3,4))])data.frame(melt(array(c(1:23, NA), c(2,3,4))))
多维列表融合pd.DataFrame(list(enumerate(list(range(1,5))+[np.NAN])))data.frame(melt(as.list(c(1:4, NA))))
数据框融合pd.melt(pd.DataFrame({'first' : ['John', 'Mary'],'last' : ['Doe', 'Bo'],'height' : [5.5, 6.0],'weight' : [130, 150]}), id_vars=['first', 'last'])melt(data.frame(first = c('John', 'Mary'),last = c('Doe', 'Bo'),height = c(5.5, 6.0),weight = c(130, 150), id=c("first", "last"))
数据透视表 pivot tablepd.pivot_table(pd.melt(pd.DataFrame({ 'x': np.random.uniform(1., 168., 12), 'y': np.random.uniform(7., 334., 12), 'z': np.random.uniform(1.7, 20.7, 12), 'month': [5,6,7]4, 'week': [1,2]6}), id_vars=['month', 'week']), values='value', index=['variable','week'],columns=['month'], aggfunc=np.mean)acast(melt(data.frame(x = runif(12, 1, 168),y = runif(12, 7, 334),z = runif(12, 1.7, 20.7),month = rep(c(5,6,7),4),week = rep(c(1,2), 6)), id=c("month", "week")), week ~ month ~ variable, mean)
连续型数值因子分类pd.cut(pd.Series([1,2,3,4,5,6]), 3)cut(c(1,2,3,4,5,6), 3)
名义型因子分类pd.Series([1,2,3,2,2,3]).astype("category")factor(c(1,2,3,2,2,3))


数据流编程对比的示例

Python的pandas中的管道操作

(df
.groupby(['a', 'b', 'c'], as_index=False)
.agg({'d': sum, 'e': mean, 'f', np.std})
.assign(g=lambda x: x.a / x.c) .query("g > 0.05")
.merge(df2, on='a'))

R 的dplyr中的管道操作

flights %>% group_by(year, month, day) %>%
select(arr_delay, dep_delay)
summarise(
arr = mean(arr_delay, na.rm = TRUE),
dep = mean(dep_delay, na.rm = TRUE)) %>%
filter(arr > 30 | dep > 30)


数据可视化对比


绘制相关性散点图

对比数据相关性是数据探索常用的一种方法,下面是Python和R的散点图对比。


Python

import seaborn as sns
import matplotlib.pyplot as plt
sns.pairplot(nba[["ast", "fg", "trb"]])
plt.show()

R

library(GGally)
ggpairs(nba[,c("ast", "fg", "trb")])

虽然我们最终得到了类似的图形,这里R中GGally是依赖于ggplot2,而Python则是在matplotlib的基础上结合Seaborn,除了GGally在R中我们还有很多其他的类似方法来实现对比制图,显然R中的绘图有更完善的生态系统。

绘制聚类效果图

这里以K-means为例,为了方便聚类,我们将非数值型或者有确实数据的列排除在外。

Python

from sklearn.cluster import KMeans
kmeans_model = KMeans(n_clusters=5, random_state=1)
good_columns = nba._get_numeric_data().dropna(axis=1)
kmeans_model.fit(good_columns)
labels = kmeans_model.labels_

from sklearn.decomposition import PCA
pca_2 = PCA(2)
plot_columns = pca_2.fit_transform(good_columns)
plt.scatter(x=plot_columns[:,0], y=plot_columns[:,1], c=labels)
plt.show()

R

library(cluster)
set.seed(1)
isGoodCol sum(is.na(col)) == 0 && is.numeric(col) }
goodCols clusters labels
nba2d twoColumns clusplot(twoColumns, labels)

速度对比

Python

import numpy as np
xx = np.zeros(100000000)
%timeit xx[:] = 1
The slowest run took 9.29 times longer than the fastest. This could mean that an intermediate result is being cached
1 loops, best of 3: 111 ms per loop

R




    
xx system.time(xx[] 
user system elapsed
1.326 0.103 1.433

显然这里R 1.326的成绩 比Python 的 Numpy 3:111的速度快了不少。

事实上,现在R和Python的数据操作的速度已经被优化得旗鼓相当了。下面是R中的 data.table、dplyr 与 Python 中的 pandas 的数据操作性能对比:

我曾经用data.table和pandas分别读取过一个600万行的IOT数据,反复10次,data.table以平均10s的成绩胜过了pandas平均15s的成绩,所以在IO上我倾向于选择使用data.table来处理大数据,然后喂给spark和hadoop进行进一步的分布式处理。

结论

Python的pandas 从R中偷师dataframes,R 中的rvest 则借鉴了 Python 的 BeautifulSoup,我们可以看出两种语言在一定程度上存在的互补性,通常,我们认为 Python比R在泛型编程上更有优势,而R在数据探索、统计分析是一种更高效的独立数据分析工具。所以说,同时学会Python和R这两把刷子才是数据科学的王道。


参考资料

  • pandas doucumentation: Comparison with R / R libraries

  • Comparison – R vs. Python: head to head data analysis

  • Hacker News: Comparison – R vs. Python

  • Quora: How does R compare with pandas?

  • yhat: R and pandas and what I've learned about each

  • Why are pandas merges in python faster than data.table merges in R?

  • Python和R科学计算操作速查表

  • 知乎:R 和 Python (numpy scipy pandas) 用于统计学分析,哪个更好?

  • Choosing R or Python for data analysis? An infographic

  • 散大大 写给Python数据科学家们 : 科学计算开发环境排雷


来腾讯课堂生信python入门和进阶

来腾讯课堂生信R入门和进阶


R统计和作图


Python


易生信系列培训课程,扫码获取免费资料

更多阅读

画图三字经 生信视频 生信系列教程 

心得体会 TCGA数据库 Linux Python 

高通量分析 免费在线画图 测序历史 超级增强子

生信学习视频 PPT EXCEL  文章写作 ggplot2

海哥组学 可视化套路 基因组浏览器

色彩搭配 图形排版 互作网络

自学生信 2019影响因子 GSEA 单细胞 

后台回复“生信宝典福利第一波”或点击阅读原文获取教程合集

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/39246
 
463 次点击