
將Python和R整合進(jìn)一個數(shù)據(jù)分析流程
在Python中調(diào)用R或在R中調(diào)用Python,為什么是“和”而不是“或”?
在互聯(lián)網(wǎng)中,關(guān)于“R Python”的文章,排名前十的搜索結(jié)果中只有2篇討論了一起使用R和Python的優(yōu)點(diǎn),而不是把這兩種語言對立起來看。這是可以理解的:這兩種語言從一開始都具有非常顯著的優(yōu)缺點(diǎn)。從歷史上看,盡管把兩者分割開來是因?yàn)榻逃尘埃航y(tǒng)計(jì)學(xué)家們傾向用R,而程序員則選擇了Python語言。然而,隨著數(shù)據(jù)科學(xué)家的增加,這種區(qū)別開始變得模糊起來:
數(shù)據(jù)科學(xué)家就是這樣一種人:軟件工程師中最懂統(tǒng)計(jì)學(xué),統(tǒng)計(jì)學(xué)家中最會編程的人。 - josh_wills在推特上這樣說到。
由于這兩種語言各自提供大量獨(dú)特的庫資源,對能夠利用這兩種語言的相對優(yōu)勢的數(shù)據(jù)科學(xué)家的需求正在不斷增長。
◆ ◆ ◆
Python與R的對比
在以下領(lǐng)域中,Python 比R 更有優(yōu)勢:
網(wǎng)絡(luò)爬蟲和數(shù)據(jù)抓?。弘m然R中的rvest已經(jīng)簡化了網(wǎng)頁抓取, Python的beautifulsoup和Scrapy更加成熟,并提供更多的功能。
數(shù)據(jù)庫連接:雖然R有大量的用于連接到數(shù)據(jù)庫的選項(xiàng), Python的sqlachemy只用了一個程序包就提供了所有的數(shù)據(jù)庫連接功能,并可廣泛用于生產(chǎn)環(huán)境。
而在以下領(lǐng)域中,R比Python更有優(yōu)勢:
統(tǒng)計(jì)分析選項(xiàng):盡管Python的SciPy和 Pandas以及 statsmodels的組合提供了很大的一套統(tǒng)計(jì)分析工具,而R是專門圍繞著統(tǒng)計(jì)分析應(yīng)用等創(chuàng)建的,因此提供了更多的相關(guān)工具。
交互式圖像或控制板:bokeh, plotly和intuitics最近都把Python的圖形使用擴(kuò)展到了Web瀏覽器,但是舉個使用shiny的例子,R中的shiny 控制面板運(yùn)行速度更快,而且往往需要更少的代碼。
此外,由于數(shù)據(jù)科學(xué)團(tuán)隊(duì)現(xiàn)在擁有一個比較廣泛的技能庫,任何應(yīng)用程序所選擇的編程語言都可能用到以前的知識和經(jīng)驗(yàn)。對于一些應(yīng)用,特別是原型設(shè)計(jì)和開發(fā)應(yīng)用,人們使用他們已知的工具則速度會更快。
純文本 的“Air Gap(網(wǎng)閘)”策略
指在完全斷開網(wǎng)絡(luò)物理連接的基礎(chǔ)上,實(shí)現(xiàn)合法信息的共享。本文中指用純文本文件實(shí)現(xiàn)兩種語言間代碼的共享——譯者注。
使用純文本作為兩種語言之間的物理隔離,你需要按如下步驟進(jìn)行。
從命令行中重構(gòu)你的R和Python腳本,并接受命令行參數(shù)。
輸出共享數(shù)據(jù)到公共文件格式。
在一種語言中執(zhí)行另一種語言,按要求傳遞參數(shù)。
優(yōu)勢:
最簡單的方法,通常最快
可以輕松查看中間輸出結(jié)果
已有常見文件格式,如: CSV , JSON , YAML的解析器
劣勢:
需要事先商定一個共同的模式或文件格式
如果流程變長的話,難以管理中間輸出結(jié)果和路徑
如果數(shù)據(jù)量變大,本地磁盤讀寫將成為瓶頸
命令行腳本
通過Windows 或Linux終端環(huán)境命令行運(yùn)行R和Python腳本類似。要運(yùn)行的命令被分解成以下部分:
<command_to_run> <path_to_script> <any_additional_arguments>
其中
<command> 是可執(zhí)行的命令 (R代碼中是 Rscript, Python代碼中是Python)
<path_to_script>是執(zhí)行腳本所在的完整或相對文件路徑。需要注意的是,如果在路徑名中有空格,整個文件路徑必須用雙引號括起來。
<any_additional_arguments>這是空格分隔的參數(shù)列表用來解析腳本本身。請注意,這些不能作為字符串傳遞。
例如,打開一個終端環(huán)境并運(yùn)行R腳本,命令如下:
Rscript path/to/myscript.R arg1 arg2 arg3
請注意以下問題:
對于Rscript 和Python 命令必須在你所在的路徑中執(zhí)行,否則你需要提供文件的完整路徑。
含有空格符的路徑名會產(chǎn)生問題,尤其是在Window系統(tǒng)中,因此必須用雙引號括起來,這樣才被認(rèn)為是一個單獨(dú)的文件路徑。
R語言中訪問命令行參數(shù)
上面的例子中,arg1,arg2 和 arg3是用來解析可執(zhí)行R腳本的參數(shù),可以使用commandArgs函數(shù)訪問
##myscript.py
#獲取命令行參數(shù)
myArgs <- commandArgs(trailingOnly = TRUE)
#myArgs是所有參數(shù)的特征向量
print(myArgs) print(class(myArgs))
通過設(shè)置trailingOnly 為TRUE,myArgs向量中只包含添加到命令行的參數(shù)。如果默認(rèn)設(shè)置為FALSE ,myArgs向量中還包含其它參數(shù),比如剛被執(zhí)行的腳本路徑。
Python語言中訪問命令行參數(shù)
通過下面的命令行執(zhí)行Python腳本:
python path/to/myscript.py arg1 arg2 arg3
通過在Python腳本中導(dǎo)入sys模塊訪問arg1, arg2 和arg3參數(shù)。 sys模塊包含了系統(tǒng)具體的參數(shù)和函數(shù),在這里,我們只對 argv的屬性感興趣。這個argv屬性是所有被傳遞到當(dāng)前正在執(zhí)行腳本的參數(shù)列表。表中的第一個元素是正在被執(zhí)行的腳本的完整路徑。
# myscript.py
import sys
# 獲取命令行參數(shù)
my_args = sys.argv
# my_args 是一個列表,其中的第一個元素是執(zhí)行的腳本
print(type(my_args))
print(my_args)
如果你只希望保留傳遞到腳本的參數(shù),你可以使用列表切片來選擇除了第一個元素以外的所有參數(shù)。
# 使用切片,選擇除第一個以外的所有元素
my_args = sys.argv[1:]
回顧一下上面的R語言例子,所有的參數(shù)需要以字符串的形式傳遞,因此有必要轉(zhuǎn)換為所期望的數(shù)據(jù)類型。
將輸出結(jié)果寫入文件
通過中間文件共享R和Python之間的數(shù)據(jù)有幾種選擇。通常,對于普通文本文件,CSVs是很好的表格數(shù)據(jù)格式,而處理可變長字段或許多嵌套數(shù)據(jù)結(jié)構(gòu)的非結(jié)構(gòu)化數(shù)據(jù)(或元數(shù)據(jù))形式時,JSON 或YAML是最好的數(shù)據(jù)格式。
這些都是很常見的數(shù)據(jù)序列化格式,在R和Python中已存在相應(yīng)的語法解析器。
在R語言中推薦下面的程序包:
對于CSV文件,使用readr
對于JSON文件,使用jsonlite
對于YAML文件,使用yaml
Python中推薦:
對于CSV文件,使用csv
對于JSON文件,使用json
對于YAML文件,使用PyYAML
csv 和json模塊是Python標(biāo)準(zhǔn)的庫文件,是Python內(nèi)置模塊,而PyYAML需要額外安裝程序包。所有的R程序包均需要安裝。
◆ ◆ ◆
總結(jié)
R 和Python之間的數(shù)據(jù)傳遞可以通過單一傳遞途徑進(jìn)行:
使用命令行傳遞參數(shù)
使用常見的結(jié)構(gòu)化文本文件傳遞數(shù)據(jù)
然而,在某些實(shí)例中,需要將文本文件作為中間文件存儲在本地,這不僅很麻煩而且還影響性能。接下來,我們將討論如何在R和Python中直接調(diào)用并在內(nèi)存中輸出。
命令行執(zhí)行和執(zhí)行子進(jìn)程
為了更好地理解在執(zhí)行子進(jìn)程的時候發(fā)生了什么,值得重新考慮當(dāng)命令行運(yùn)行一個Python 或 R進(jìn)程中更多的細(xì)節(jié)。在運(yùn)行下面的命令時,啟動了一個新的 Python 進(jìn)程執(zhí)行該腳本。
在執(zhí)行過程中,任何被輸出到標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤流的數(shù)據(jù)會返回到控制臺顯示。最常見的實(shí)現(xiàn)方式是通過Python中的一個內(nèi)置函數(shù)print()或是 R中的函數(shù) cat()和 print(),它們將給定字符串的寫入標(biāo)準(zhǔn)輸出流。一旦腳本執(zhí)行完畢,Python進(jìn)程隨即關(guān)閉。
在這種方式下運(yùn)行命令行腳本是有用的,但如果希望用這個方法執(zhí)行多個連續(xù)卻相互獨(dú)立腳本時,就變得繁瑣,并且容易出錯。然而,這可能讓一個Python或R進(jìn)程直接去執(zhí)行另一個類似的命令。這樣有好處,即從一個Python父進(jìn)程啟動一個R中的子進(jìn)程去運(yùn)行特定的腳本,進(jìn)而完成分析。一旦R腳本運(yùn)行完畢,R中子進(jìn)程的輸出不是被傳到控制臺,而是返回到父進(jìn)程中。使用這種方法除去了手動單獨(dú)執(zhí)行命令行的步驟。
實(shí)例
為了說明一個進(jìn)程的執(zhí)行是由另一個進(jìn)程引起的,我們將會用兩個簡單的例子:一個是Python調(diào)用R,另一個是R調(diào)用Python。我們?nèi)藶榻档土嗣總€案例中分析結(jié)果的重要性,以便把重點(diǎn)放在機(jī)器是如何的實(shí)現(xiàn)的過程上。
R腳本范例
我們簡單的R腳本例子要從命令行獲取一系列數(shù)字并返回最大值。
# max.R
# 獲取命令行參數(shù)
myArgs <- commandArgs(trailingOnly = TRUE)
# 轉(zhuǎn)換成數(shù)字類型
nums = as.numeric(myArgs)
# cat將把結(jié)果寫入標(biāo)準(zhǔn)輸出流
cat(max(nums))
在Python中執(zhí)行R腳本
我們需要利用子進(jìn)程的模塊,也就是標(biāo)準(zhǔn)庫的一部分,來實(shí)現(xiàn)從Python中進(jìn)行調(diào)用。我們將使用函數(shù)check_output 來調(diào)用 R 腳本,執(zhí)行命令并存儲標(biāo)準(zhǔn)輸出的結(jié)果。
想要在Python中調(diào)用R來執(zhí)行 max.R腳本,首先要建立要運(yùn)行的命令。在Python中的形式以一個字符串列表表示,其相應(yīng)的元素如下所示:
['<command_to_run>', '<path_to_script>', 'arg1' , 'arg2', 'arg3', 'arg4']
下面代碼是運(yùn)行在Python中調(diào)用R的一個例子:
# run_max.py
import subprocess
# 定義命令和參數(shù)
command = 'Rscript'
path2script = 'path/to your script/max.R'
# args變量的值是一個列表
args = ['11', '3', '9', '42']
#建立子進(jìn)程命令
cmd = [command, path2script] + args
# check_output會執(zhí)行命令并存儲結(jié)果
x = subprocess.check_output(cmd, universal_newlines=True)
print('The maximum of the numbers is:', x)
參數(shù) universal_newlines=True 告訴 Python 把返回的輸出結(jié)果解釋為文本字符串,并處理 Windows 和 Linux 的換行字符。如果省略了這個,則輸出結(jié)果會被作為一個字節(jié)的字符串返回,同時在進(jìn)行任何字符串進(jìn)一步操作之前必須調(diào)用x.decode()來解碼成文本。
Python 腳本范例
在我們簡單的 Python 腳本中,我們將給定的字符串(第一個參數(shù))拆分為基于所提供的字符串模式的多個子字符串 (第二個參數(shù))。然后,結(jié)果以每行一個子字符串的形式輸出到控制臺。
# splitstr.py
import sys
# 獲取傳入的參數(shù)
string = sys.argv[1]
pattern = sys.argv[2]
#執(zhí)行分割
ans = string.split(pattern)
#把所產(chǎn)生的元素列表合成一個新命令行
# 分割字符串并打印
print('\n'.join(ans))
在R中調(diào)用Python
當(dāng)用R執(zhí)行子進(jìn)程時,建議使用 R 的system2函數(shù)來執(zhí)行并獲取輸出。這是因?yàn)閮?nèi)置的系統(tǒng)函數(shù)跨平臺不兼容,非常難使用。
建立要執(zhí)行的命令是類似于上面的 Python 例子,然而system2 期望命令根據(jù)它的參數(shù)被分解開來。此外,這些參數(shù)首先必須總是正在執(zhí)行的腳本的路徑。
最后一個困難可能是R腳本路徑名稱中的空格處理引起的。解決這一問題最簡單的方法是為全路徑名稱加上雙引號,然后用單引號封裝此字符串,這樣,R保留參數(shù)本身的雙引號。
下面的代碼中,給出在R 中執(zhí)行 Python 腳本的實(shí)例。
# run_splitstr.R
command = "python"
#注意在字符串中的單引號和雙引號(如果路徑名中有空格,這是必須的)
path2script='"path/to your script/splitstr.py"'
# 設(shè)置args成向量
string = "3523462---12413415---4577678---7967956---5456439"
pattern = "---"
args = c(string, pattern)
# 把腳本路徑加入,成為第一個arg參數(shù)
allArgs = c(path2script, args)
output = system2(command, args=allArgs, stdout=TRUE)
print(paste("The Substrings are:\n", output))
為了獲取標(biāo)準(zhǔn)輸出中的特征向量(每個元素一行),stdout=TRUE 必須在system2中具體說明,不然返回的只是退出狀態(tài)。當(dāng)stdout=TRUE時,退出狀態(tài)存儲在一個名為“狀態(tài)”的屬性中。
總結(jié)
通過子進(jìn)程調(diào)用,可以將Python和R語言整合到一個應(yīng)用程序中。這允許一個父進(jìn)程調(diào)用另一個進(jìn)程作為子進(jìn)程,并獲取任何輸出到標(biāo)準(zhǔn)輸出的結(jié)果。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計(jì)的實(shí)用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實(shí)施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預(yù)測分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢預(yù)判? ? 在數(shù)據(jù)驅(qū)動決策的時代,預(yù)測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點(diǎn),而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗(yàn):捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗(yàn)如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實(shí)戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗(yàn):數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨(dú)特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計(jì)學(xué)方法在市場調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場調(diào)研是企業(yè)洞察市場動態(tài)、了解消費(fèi)者需求的重要途徑,而統(tǒng)計(jì)學(xué)方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03