Python&R語言-將Python和R整合進一個數據分析流程


命令行腳本

通過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中的形式以一個字符串列表表示,其相應的元素如下所示:[‘’, ‘’, ‘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整合到一個應用程序中。這允許一個父進程調用另一個進程作為子進程,並獲取任何輸出到標准輸出的結果。

來源:大數據文摘



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM