熱線電話:13121318867

登錄
首頁精彩閱讀將Python和R整合進一個數據分析流程
將Python和R整合進一個數據分析流程
2016-08-21
收藏

將Python和R整合進一個數據分析流程

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

在互聯網中,關于“R Python”的文章,排名前十的搜索結果中只有2篇討論了一起使用R和Python的優點,而不是把這兩種語言對立起來看。這是可以理解的:這兩種語言從一開始都具有非常顯著的優缺點。從歷史上看,盡管把兩者分割開來是因為教育背景:統計學家們傾向用R,而程序員則選擇了Python語言。然而,隨著數據科學家的增加,這種區別開始變得模糊起來:

數據科學家就是這樣一種人:軟件工程師中最懂統計學,統計學家中最會編程的人。 - josh_wills在推特上這樣說到。

由于這兩種語言各自提供大量獨特的庫資源,對能夠利用這兩種語言的相對優勢的數據科學家的需求正在不斷增長。

◆ ◆ ◆

Python與R的對比

在以下領域中,Python 比R 更有優勢:

  • 網絡爬蟲和數據抓?。弘m然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腳本類似。要運行的命令被分解成以下部分:

<command_to_run> <path_to_script> <any_additional_arguments>

其中

  • <command> 是可執行的命令 (R代碼中是 Rscript, Python代碼中是Python)

  • <path_to_script>是執行腳本所在的完整或相對文件路徑。需要注意的是,如果在路徑名中有空格,整個文件路徑必須用雙引號括起來。

  • <any_additional_arguments>這是空格分隔的參數列表用來解析腳本本身。請注意,這些不能作為字符串傳遞。

例如,打開一個終端環境并運行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中的形式以一個字符串列表表示,其相應的元素如下所示:

['<command_to_run>', '<path_to_script>', '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語言整合到一個應用程序中。這允許一個父進程調用另一個進程作為子進程,并獲取任何輸出到標準輸出的結果。


數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢