
將Python和R整合進一個數(shù)據(jù)分析流程
在Python中調(diào)用R或在R中調(diào)用Python,為什么是“和”而不是“或”?
在互聯(lián)網(wǎng)中,關(guān)于“R Python”的文章,排名前十的搜索結(jié)果中只有2篇討論了一起使用R和Python的優(yōu)點,而不是把這兩種語言對立起來看。這是可以理解的:這兩種語言從一開始都具有非常顯著的優(yōu)缺點。從歷史上看,盡管把兩者分割開來是因為教育背景:統(tǒng)計學家們傾向用R,而程序員則選擇了Python語言。然而,隨著數(shù)據(jù)科學家的增加,這種區(qū)別開始變得模糊起來:
數(shù)據(jù)科學家就是這樣一種人:軟件工程師中最懂統(tǒng)計學,統(tǒng)計學家中最會編程的人。 - josh_wills在推特上這樣說到。
由于這兩種語言各自提供大量獨特的庫資源,對能夠利用這兩種語言的相對優(yōu)勢的數(shù)據(jù)科學家的需求正在不斷增長。
◆ ◆ ◆
Python與R的對比
在以下領(lǐng)域中,Python 比R 更有優(yōu)勢:
網(wǎng)絡(luò)爬蟲和數(shù)據(jù)抓取:雖然R中的rvest已經(jīng)簡化了網(wǎng)頁抓取, Python的beautifulsoup和Scrapy更加成熟,并提供更多的功能。
數(shù)據(jù)庫連接:雖然R有大量的用于連接到數(shù)據(jù)庫的選項, Python的sqlachemy只用了一個程序包就提供了所有的數(shù)據(jù)庫連接功能,并可廣泛用于生產(chǎn)環(huán)境。
而在以下領(lǐng)域中,R比Python更有優(yōu)勢:
統(tǒng)計分析選項:盡管Python的SciPy和 Pandas以及 statsmodels的組合提供了很大的一套統(tǒng)計分析工具,而R是專門圍繞著統(tǒng)計分析應(yīng)用等創(chuàng)建的,因此提供了更多的相關(guān)工具。
交互式圖像或控制板:bokeh, plotly和intuitics最近都把Python的圖形使用擴展到了Web瀏覽器,但是舉個使用shiny的例子,R中的shiny 控制面板運行速度更快,而且往往需要更少的代碼。
此外,由于數(shù)據(jù)科學團隊現(xiàn)在擁有一個比較廣泛的技能庫,任何應(yīng)用程序所選擇的編程語言都可能用到以前的知識和經(jīng)驗。對于一些應(yīng)用,特別是原型設(shè)計和開發(fā)應(yīng)用,人們使用他們已知的工具則速度會更快。
純文本 的“Air Gap(網(wǎng)閘)”策略
指在完全斷開網(wǎng)絡(luò)物理連接的基礎(chǔ)上,實現(xiàn)合法信息的共享。本文中指用純文本文件實現(xiàn)兩種語言間代碼的共享——譯者注。
使用純文本作為兩種語言之間的物理隔離,你需要按如下步驟進行。
從命令行中重構(gòu)你的R和Python腳本,并接受命令行參數(shù)。
輸出共享數(shù)據(jù)到公共文件格式。
在一種語言中執(zhí)行另一種語言,按要求傳遞參數(shù)。
優(yōu)勢:
最簡單的方法,通常最快
可以輕松查看中間輸出結(jié)果
已有常見文件格式,如: CSV , JSON , YAML的解析器
劣勢:
需要事先商定一個共同的模式或文件格式
如果流程變長的話,難以管理中間輸出結(jié)果和路徑
如果數(shù)據(jù)量變大,本地磁盤讀寫將成為瓶頸
命令行腳本
通過Windows 或Linux終端環(huán)境命令行運行R和Python腳本類似。要運行的命令被分解成以下部分:
<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)境并運行R腳本,命令如下:
Rscript path/to/myscript.R arg1 arg2 arg3
請注意以下問題:
對于Rscript 和Python 命令必須在你所在的路徑中執(zhí)行,否則你需要提供文件的完整路徑。
含有空格符的路徑名會產(chǎn)生問題,尤其是在Window系統(tǒng)中,因此必須用雙引號括起來,這樣才被認為是一個單獨的文件路徑。
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ù)。如果默認設(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屬性是所有被傳遞到當前正在執(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標準的庫文件,是Python內(nèi)置模塊,而PyYAML需要額外安裝程序包。所有的R程序包均需要安裝。
◆ ◆ ◆
總結(jié)
R 和Python之間的數(shù)據(jù)傳遞可以通過單一傳遞途徑進行:
使用命令行傳遞參數(shù)
使用常見的結(jié)構(gòu)化文本文件傳遞數(shù)據(jù)
然而,在某些實例中,需要將文本文件作為中間文件存儲在本地,這不僅很麻煩而且還影響性能。接下來,我們將討論如何在R和Python中直接調(diào)用并在內(nèi)存中輸出。
命令行執(zhí)行和執(zhí)行子進程
為了更好地理解在執(zhí)行子進程的時候發(fā)生了什么,值得重新考慮當命令行運行一個Python 或 R進程中更多的細節(jié)。在運行下面的命令時,啟動了一個新的 Python 進程執(zhí)行該腳本。
在執(zhí)行過程中,任何被輸出到標準輸出和標準錯誤流的數(shù)據(jù)會返回到控制臺顯示。最常見的實現(xiàn)方式是通過Python中的一個內(nèi)置函數(shù)print()或是 R中的函數(shù) cat()和 print(),它們將給定字符串的寫入標準輸出流。一旦腳本執(zhí)行完畢,Python進程隨即關(guān)閉。
在這種方式下運行命令行腳本是有用的,但如果希望用這個方法執(zhí)行多個連續(xù)卻相互獨立腳本時,就變得繁瑣,并且容易出錯。然而,這可能讓一個Python或R進程直接去執(zhí)行另一個類似的命令。這樣有好處,即從一個Python父進程啟動一個R中的子進程去運行特定的腳本,進而完成分析。一旦R腳本運行完畢,R中子進程的輸出不是被傳到控制臺,而是返回到父進程中。使用這種方法除去了手動單獨執(zhí)行命令行的步驟。
實例
為了說明一個進程的執(zhí)行是由另一個進程引起的,我們將會用兩個簡單的例子:一個是Python調(diào)用R,另一個是R調(diào)用Python。我們?nèi)藶榻档土嗣總€案例中分析結(jié)果的重要性,以便把重點放在機器是如何的實現(xiàn)的過程上。
R腳本范例
我們簡單的R腳本例子要從命令行獲取一系列數(shù)字并返回最大值。
# max.R
# 獲取命令行參數(shù)
myArgs <- commandArgs(trailingOnly = TRUE)
# 轉(zhuǎn)換成數(shù)字類型
nums = as.numeric(myArgs)
# cat將把結(jié)果寫入標準輸出流
cat(max(nums))
在Python中執(zhí)行R腳本
我們需要利用子進程的模塊,也就是標準庫的一部分,來實現(xiàn)從Python中進行調(diào)用。我們將使用函數(shù)check_output 來調(diào)用 R 腳本,執(zhí)行命令并存儲標準輸出的結(jié)果。
想要在Python中調(diào)用R來執(zhí)行 max.R腳本,首先要建立要運行的命令。在Python中的形式以一個字符串列表表示,其相應(yīng)的元素如下所示:
['<command_to_run>', '<path_to_script>', 'arg1' , 'arg2', 'arg3', 'arg4']
下面代碼是運行在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']
#建立子進程命令
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é)的字符串返回,同時在進行任何字符串進一步操作之前必須調(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
當用R執(zhí)行子進程時,建議使用 R 的system2函數(shù)來執(zhí)行并獲取輸出。這是因為內(nèi)置的系統(tǒng)函數(shù)跨平臺不兼容,非常難使用。
建立要執(zhí)行的命令是類似于上面的 Python 例子,然而system2 期望命令根據(jù)它的參數(shù)被分解開來。此外,這些參數(shù)首先必須總是正在執(zhí)行的腳本的路徑。
最后一個困難可能是R腳本路徑名稱中的空格處理引起的。解決這一問題最簡單的方法是為全路徑名稱加上雙引號,然后用單引號封裝此字符串,這樣,R保留參數(shù)本身的雙引號。
下面的代碼中,給出在R 中執(zhí)行 Python 腳本的實例。
# 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))
為了獲取標準輸出中的特征向量(每個元素一行),stdout=TRUE 必須在system2中具體說明,不然返回的只是退出狀態(tài)。當stdout=TRUE時,退出狀態(tài)存儲在一個名為“狀態(tài)”的屬性中。
總結(jié)
通過子進程調(diào)用,可以將Python和R語言整合到一個應(yīng)用程序中。這允許一個父進程調(diào)用另一個進程作為子進程,并獲取任何輸出到標準輸出的結(jié)果。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計學領(lǐng)域,假設(shè)檢驗是驗證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當下,精準營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實踐到業(yè)務(wù)價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導(dǎo)向 統(tǒng)計模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10CDA 數(shù)據(jù)分析師:商業(yè)數(shù)據(jù)分析實踐的落地者與價值創(chuàng)造者 商業(yè)數(shù)據(jù)分析的價值,最終要在 “實踐” 中體現(xiàn) —— 脫離業(yè)務(wù)場景的分 ...
2025-09-10機器學習解決實際問題的核心關(guān)鍵:從業(yè)務(wù)到落地的全流程解析 在人工智能技術(shù)落地的浪潮中,機器學習作為核心工具,已廣泛應(yīng)用于 ...
2025-09-09SPSS 編碼狀態(tài)區(qū)域中 Unicode 的功能與價值解析 在 SPSS(Statistical Product and Service Solutions,統(tǒng)計產(chǎn)品與服務(wù)解決方案 ...
2025-09-09