編者按:數(shù)據(jù)科學(xué)家Alan Marazzi這篇討論R和Python哪個對數(shù)據(jù)科學(xué)初學(xué)者更友好的文章有些偏向R語言,結(jié)論僅供參考。不過,它出色地展示了R語言在數(shù)據(jù)問題上犀利的表達力。對初學(xué)者而言,從高層抽象(由R語言中的原生結(jié)構(gòu)或Numpy之類的Python第三方庫提供)入手也確實更加便利。
這不是你通常在網(wǎng)上看到的那類爭論R和Python哪個好的帖子。事實上,我根本不想討論到底哪個好。我只想說明,想要入門數(shù)據(jù)科學(xué)的學(xué)習(xí)者,從R開始更合適。
向量
什么是向量?如果你知道矩陣,那你就知道向量。向量可以看成矩陣的行或列,也就是由數(shù)字組成的一維“列表”。通常向量用作數(shù)據(jù)表的列,因為我們確信同一列內(nèi)的數(shù)據(jù)類型相同。
浮點數(shù)、整數(shù)、字符串、類別,等等,向量中的元素總是屬于同一類型。這很重要,因為我們可以利用這一點加速和簡化代碼:解釋器只需檢查第一項記錄的類型。你也許已經(jīng)知道,向量是R的原生結(jié)構(gòu),事實上,R中標(biāo)量也是向量(一維向量)。
vec <- c(5, 3, 4)
class(vec)
[1] "numeric"
class(3)
[1] "numeric"
向量化
進行數(shù)據(jù)分析或機器學(xué)習(xí)時,常常需要處理表格形式的數(shù)據(jù),或者,從更底層的角度來說,向量的序列。如果我想將向量中的每項記錄乘2,在R中我可以非常自然地做到這一點:
vec * 2
[1] 1068
Python中,向量不是原生結(jié)構(gòu),不過我們可以使用列表存儲向量。所以讓我們在Python 3中嘗試相同的操作(你需要操心到底用Python 2還是Python 3是另一個問題):
>>> [5, 3, 4] * 2
[5, 3, 4, 5, 3, 4]
搞什么……
在Python中要得到同樣的結(jié)果,你需要使用for循環(huán):
>>> for num in [5, 3, 4]:
... num * 2
...
10
6
8
你可能需要把結(jié)果存儲到另一個列表中,所以你需要首先初始化一個空列表來存放結(jié)果,然后啟動循環(huán),在每個迭代中添加結(jié)果:
>>> res = []
>>> for num in [5, 3, 4]:
... res.append(num * 2)
...
>>> print(res)
[10, 6, 8]
在R中,你只需:
vec <- c(5, 3, 4) * 2
vec
[1] 1068
(譯者注:不考慮引入numpy等第三方庫的情況下,用Python的列表理解表達要簡潔許多:[i * 2 for i in [5, 3, 4]])
我想強調(diào)的是,這主要不是少打幾個字的問題,而是形成“恰當(dāng)?shù)摹毙闹悄P偷膯栴}。許多人抱怨R代碼很慢,99%是因為沒有向量化他們的代碼,而使用“Python風(fēng)格”的循環(huán)(隱式或顯式)。
隨機行走例子
我們將分別在R和Python中實現(xiàn)隨機行走,Python代碼取自《From Python to NumPy》一書。
讓我們從最基本的循環(huán)方式開始:
>>> import random # 需要引入random模塊
>>> def random_walk(n):
... position = 0# 初始化位置變量
... walk = [position] # 初始化列表
... for i in range(n):
... position += 2*random.randint(0, 1)-1# 更新位置值
... walk.append(position) # 附加結(jié)果至行走列表
... return walk
...
如果對象非常大,上面的代碼會變得很慢,我們可以使用itertools模塊改善性能:
>>> from itertools import accumulate
>>> import random
>>> def random_walk_faster(n=1000):
... steps = random.sample([1, -1]*n, n)
... return list(accumulate(steps))
...
不過,這還是沒有向量化。它不過是更高效的循環(huán)而已。要做到完全向量化,我們需要使用NumPy:
>>> import numpy as np
>>> def random_walk_fastest(n=1000):
... steps = 2*np.random.randint(0, 2, size=n) - 1
... return np.cumsum(steps)
...
換成R語言:
rw <- cumsum(sample(c(-1, 1), 1000, TRUE))
無需引入什么模塊,無需額外定義什么函數(shù)或方法,一行搞定。(譯者注:Python確實需要引入NumPy,但其實也不用額外定義函數(shù),np.cumsum(np.random.randint(...)))。
結(jié)語
如果你想從事和數(shù)據(jù)打交道的工作,或者想要教別人如何處理數(shù)據(jù),可以從R開始。熟練使用R之后,再開始學(xué)Python比較好。
-
向量
+關(guān)注
關(guān)注
0文章
55瀏覽量
11666 -
python
+關(guān)注
關(guān)注
56文章
4797瀏覽量
84690 -
r語言
+關(guān)注
關(guān)注
1文章
30瀏覽量
6288
原文標(biāo)題:數(shù)據(jù)科學(xué)入門,先學(xué)R再學(xué)Python
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論