资讯专栏INFORMATION COLUMN

[原]深入对比数据科学工具箱:Python和R之争[2016版]

whidy / 2305人阅读

摘要:概述在真实的数据科学世界里,我们会有两个极端,一个是业务,一个是工程。偏向业务的数据科学被称为数据分析,也就是型数据科学。所以说,同时学会和这两把刷子才是数据科学的王道。

概述

在真实的数据科学世界里,我们会有两个极端,一个是业务,一个是工程。偏向业务的数据科学被称为数据分析(Data Analysis),也就是A型数据科学。偏向工程的数据科学被称为数据构建(Data Building),也就是B型数据科学。

从工具上来看,按由业务到工程的顺序,这个两条是:EXCEL >> R >> Python >> Scala

在实际工作中,对于小数据集的简单分析来说,使用EXCEL绝对是最佳选择。当我们需要更多复杂的统计分析和数据处理时,我们就需要转移到 Python 和 R 上。在确定工程实施和大数据集操作时,我们就需要依赖 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 都可以通过命令行的方式和其他语言做交互,通过命令行而不是直接调用某个类或方法可以更好地降低耦合性,在提高团队协作的效率。

参数传递 Python R
命令行输入 Python path/to/myscript.py arg1 arg2 arg3 Rscript path/to/myscript.R arg1 arg2 arg3
脚本识别 import sys my_args = sys.argv myArgs <- commandArgs(trailingOnly = TRUE)
数据传输与解析

对于数据传输与解析,我们首推的格式是csv,因为一方面,csv格式的读写解析都可以通过 Python 和 R 的原生函数完成,不需要再安装其他包。另一方面,csv格式可以很快的转化为 data frame 格式,而data frame 格式是数据流分析的核心。

不过,实际情况中,我们需要传输一些非结构化的数据,这时候就必须用到 JSNO 或者 YAML。

数据传输与解析 Python R
CSV(原生) csv read.csv
CSV(优化) pandas.read_csv("nba_2013.csv") data.table::fread("nba_2013.csv")
JSON json(原生) jsonlite
YAML PyYAML yaml
基本数据结构

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

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

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

R 中数据结构转化(plyr) list data frame array
list llply() ldply() laply()
data frame dlply() ddply() daply()
array alply() adply() aaply()
MapReduce
Python R
map Map
reduce Reduce
filter filter
矩阵操作

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

矩阵转化 Pyhton R
维度 data.shape dim(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.T t(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)
矩阵计算 Pyhton R
矩阵乘法 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的语法。

数据框操作 Python R
按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/F pd.Series(np.arange(5),dtype=np.float32).isin([2, 4]) 0:4 %in% c(2,4)
match 匹配操作 返回Index pd.Series(pd.match(pd.Series(np.arange(5),dtype=np.float32),[2,4],np.nan)) match(0:4, c(2,4))
tapply df.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 table pd.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 <- function(col){
   sum(is.na(col)) == 0 && is.numeric(col) 
}
goodCols <- sapply(nba, isGoodCol)
clusters <- kmeans(nba[,goodCols], centers=5)
labels <- clusters$cluster

nba2d <- prcomp(nba[,goodCols], center=TRUE)
twoColumns <- nba2d$x[,1:2]
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 <- rep(0, 100000000)
system.time(xx[] <- 1)
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数据科学家们 : 科学计算开发环境排雷

作为分享主义者(sharism),本人所有互联网发布的图文均遵从CC版权,转载请保留作者信息并注明作者 Harry Zhu 的 FinanceR专栏:https://segmentfault.com/blog...,如果涉及源代码请注明GitHub地址:https://github.com/harryprince。微信号: harryzhustudio
商业使用请联系作者。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37871.html

相关文章

  • PythonR、Matlab的对比

    摘要:我们来看一下美国相关专业人员对两者的对比,只是粗略而不精准的翻译一下。小结其实在写这篇文章之前,我就问过一下包括清华在内的学校以及一些数学专业的学生,和还是占主流,但是经过一番调查发现在美国在数据科学数学等方面好像渐成压倒性的优势。 作为一枚程序员,想要研究Python编程语言与数学学习(教学)的结合,就不能不了解以及比对一下其他数学学习与应用的解决方案,比如R语言、Matlab等数学...

    yunhao 评论0 收藏0
  • []深入对比数据科学具箱PythonR 的 Web 编辑器

    摘要:概述工欲善其事必先利其器,如果现在要评选数据科学中最好用的编辑器注意一定是可以通过访问的,和一定是角逐的最大热门,正确使用编辑器可以很大地提升我们的工作效率。 概述 showImg(https://segmentfault.com/img/bVAdol); 工欲善其事必先利其器,如果现在要评选数据科学中最好用的Web 编辑器(注意一定是可以通过Web访问的),RStudio和Jupyt...

    RobinQu 评论0 收藏0
  • [] 深入对比数据科学具箱Python R 的异常处理机制

    摘要:对于异常机制的合理运用是直接关系到码农饭碗的事情所以,本文将具体介绍一下和的异常处理机制,阐明二者在异常处理机制上的异同。下面将具体介绍二者的异常处理机制。 概述 showImg(https://segmentfault.com/img/remote/1460000006760426); 异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正...

    FreeZinG 评论0 收藏0
  • []深入对比数据科学具箱PythonR 非结构化数据的结构化

    摘要:则在读取数据时将两个中文字段混淆成了一个字段,导致整个数据结构错乱。三条路子全军覆没,这让我情何以堪,好在使用的经验颇丰,通过中文的转换和切割就轻松解决了这个问题。 概述 showImg(https://segmentfault.com/img/bVylLL); 在现实场景中,由于数据来源的异构,数据源的格式往往是难以统一的,这就导致大量具有价值的数据通常是以非结构化的形式聚合在一起的...

    leiyi 评论0 收藏0
  • [译] 深入对比数据科学具箱Python R 的 C/C++ 实现

    摘要:另外一个我们同时使用两种语言的原因是已有的统计学工具与包。对另一些为读者写数据科学工具的人来说他们从一开始就考虑了这些跨语言。和实际上是用实现的这是条阻力最小的路径。无论是哪个赢得这场语言战争,和都将保持在数据科学届的地位。 showImg(https://segmentfault.com/img/remote/1460000006762469); 概述 几周前,我有幸在 Scipy ...

    jimhs 评论0 收藏0

发表评论

0条评论

whidy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<