做數(shù)據(jù)分析時(shí),R 用戶如何學(xué)習(xí) Python?
本文是幫助 R 用戶增強(qiáng)技能和為數(shù)據(jù)科學(xué)進(jìn)階而學(xué)習(xí) Python (從零開(kāi)始)。畢竟,R 和 Python 是數(shù)據(jù)科學(xué)從業(yè)者必需掌握的兩門最重要的編程語(yǔ)言。
Python 是一門功能強(qiáng)大和多用途的編程語(yǔ)言,在過(guò)去幾年取得驚人發(fā)展。它過(guò)去用于 Web 開(kāi)發(fā)和游戲開(kāi)發(fā),現(xiàn)在數(shù)據(jù)分析和機(jī)器學(xué)習(xí)也要用到它。數(shù)據(jù)分析和機(jī)器學(xué)習(xí)是 Python 應(yīng)用上相對(duì)新的分支。
作為初學(xué)者,學(xué)習(xí) Python 來(lái)做數(shù)據(jù)分析是比較痛苦的。為什么?
在谷歌上搜索“Learn Python ”,你會(huì)搜到海量教程,但內(nèi)容只是關(guān)于學(xué)習(xí) Python 做 Web 開(kāi)發(fā)應(yīng)用。那你如何找到方法?
在本教程,我們將探討 Python 在執(zhí)行數(shù)據(jù)操作任務(wù)上的基礎(chǔ)知識(shí)。同時(shí),我們還將對(duì)比在 R 上是如何操作的。這種并行比較有助于你將 R 和 Python 上的任務(wù)聯(lián)系起來(lái)。***,我們將采用一個(gè)數(shù)據(jù)集來(lái)練習(xí)我們新掌握的 Python 技能。
注意:閱讀這篇文章時(shí)***具備一定的 R 基礎(chǔ)知識(shí)。
內(nèi)容概要
- 為什么學(xué)習(xí) Python(即使你已經(jīng)懂 R )
- 理解 Python 的數(shù)據(jù)類型和結(jié)構(gòu)(與 R 對(duì)比)
- 用 Python 寫代碼(與 R 對(duì)比)
- 用一個(gè)數(shù)據(jù)集實(shí)踐 Python
為什么學(xué)習(xí) Python(即使你已經(jīng)懂R)
毫無(wú)疑問(wèn),R 在它自身的領(lǐng)域是極其強(qiáng)大的,實(shí)際上,它最初是用來(lái)做統(tǒng)計(jì)計(jì)算和操作。強(qiáng)大的社區(qū)支持使得初學(xué)者可以很快掌握 R .
但是, Python 正迎頭趕上,無(wú)論成熟公司還是初創(chuàng)公司對(duì)Python 的接受程度要遠(yuǎn)遠(yuǎn)大于 R 。
根據(jù) indeed.com 提供的數(shù)據(jù)(2016年1月至2016年12月),“用 Python 做機(jī)器學(xué)習(xí)”的招聘信息數(shù)量要比“用 R 做機(jī)器學(xué)習(xí)” 增長(zhǎng)快得多(約 123%)。這是因?yàn)椋?/p>
Python 以更好的方式支持機(jī)器學(xué)習(xí)覆蓋的全部范圍。
Python 不僅支持模型構(gòu)建,而且支持模型部署。
相比 R , Python 支持多種強(qiáng)大的諸如 keras、convnet,、theano 和 tensorflow 深度學(xué)習(xí)庫(kù)。
Python的庫(kù)相對(duì)獨(dú)立,每個(gè)庫(kù)都擁有數(shù)據(jù)科學(xué)工作者所需要的所有函數(shù)。你不需要像在 R 中一樣在各種包之間來(lái)回查找一個(gè)函數(shù)。
理解 Python 數(shù)據(jù)類型和結(jié)構(gòu)(與 R 對(duì)比)
編程語(yǔ)言是基于它的變量和數(shù)據(jù)類型來(lái)理解復(fù)雜的數(shù)據(jù)集。是的,假設(shè)你有一個(gè) 100 萬(wàn)行,50 列的數(shù)據(jù)集。編程語(yǔ)言會(huì)如何理解這些數(shù)據(jù)呢?
基本上,R 和 Python 都有未定義數(shù)據(jù)類型。獨(dú)立和非獨(dú)立變量都有著不同的數(shù)據(jù)類型。解釋器根據(jù)數(shù)據(jù)類型分配內(nèi)存。Python 支持的數(shù)據(jù)類型包括:
1.數(shù)值型(Numbers)——存儲(chǔ)數(shù)值。這些數(shù)值可以存儲(chǔ)為4種類型:整型,長(zhǎng)整型,浮點(diǎn)型,復(fù)數(shù)型。讓我們分別理解。
- 整型(Integer)—— 它指的是整數(shù)類型,比如 10 、13 、91、102 等。相當(dāng)于 R 中的整型(integer)。
- 長(zhǎng)整型(Long)——它指的是用八進(jìn)制或者十六進(jìn)制表示的長(zhǎng)整數(shù),在 R 中,用 64 位包讀取十六進(jìn)制值。
- 浮點(diǎn)型(Float)——指的是小數(shù)值,比如 1.23 , 9.89 等, R 中浮點(diǎn)數(shù)包含在數(shù)值型(numeric)。
- 復(fù)數(shù)型(Complex)——它指的是復(fù)數(shù)值,比如 as 2 + 3i, 5i 等。不過(guò)這種數(shù)據(jù)類型在數(shù)據(jù)中不太常見(jiàn)。
2.布爾型(Boolean)——布爾型只存儲(chǔ)兩個(gè)值(True 和 False)。在 R 中,它可以存儲(chǔ)為因子(factor)類型或字符(character)類型。R 和 Python 的布爾值之間存在著微小的差別。在 R 中,布爾型存儲(chǔ)為 TRUE 和 FALSE。在 Python 中,它們存儲(chǔ)為 True 和 False 。字母的情況有差異。
3.字符串(Strings)——它存儲(chǔ)文本(字符)數(shù)據(jù),如“elephant,”lotus,”等,相當(dāng)于R的字符型(character)。
4.列表——它與 R 的列表數(shù)據(jù)類型相同。它能夠存儲(chǔ)多種變量類型的值,如字符串、整數(shù)、布爾值等。
5.元組—— R 中沒(méi)有元組類型,把元組看成是 R 中的向量,它的值不能改變。即它是不可變的。
6.字典—— 它提供支持 key-value 對(duì)的二維結(jié)構(gòu)。簡(jiǎn)而言之,把鍵(key )看作是列名,對(duì)(pair)看作是列值。
因?yàn)?R 是統(tǒng)計(jì)計(jì)算語(yǔ)言,所有操作數(shù)據(jù)和讀取變量的函數(shù)都是固有的。而另一方面,Python 數(shù)據(jù)的分析、處理、可視化函數(shù)都是從外部庫(kù)調(diào)用。Python 有多個(gè)用于數(shù)據(jù)操作和機(jī)器學(xué)習(xí)的庫(kù)。以下列舉最重要的幾個(gè):
- Numpy——在Python中它用于進(jìn)行數(shù)值計(jì)算。它提供了龐大的諸如線性代數(shù)、統(tǒng)計(jì)等的數(shù)學(xué)函數(shù)庫(kù)。它主要用于創(chuàng)建數(shù)組。在 R 中,把數(shù)組看作列表。它包含一個(gè)類(數(shù)字或字符串或布爾)或多個(gè)類。它可以是一維或多維的。
- Scipy ——在Python中它用于進(jìn)行科學(xué)計(jì)算。
- Matplotlib——在 Python 中它用于進(jìn)行數(shù)據(jù)可視化。在 R,我們使用著名的 ggplot2 庫(kù)。
- Pandas ——對(duì)于數(shù)據(jù)處理任務(wù)它極其強(qiáng)大。在 R 中,我們使用 dplyr,data.table 等包。
- Scikit Learn—— 它是實(shí)現(xiàn)機(jī)器學(xué)習(xí)算法的強(qiáng)大工具。實(shí)際上,它也是 python 中用來(lái)做機(jī)器學(xué)習(xí)的***工具。它包含建模所需的所有函數(shù)。
在某種程度上,對(duì)于數(shù)據(jù)科學(xué)工作者來(lái)說(shuō),最主要的是要掌握上面提到的 Python 庫(kù)。但人們正開(kāi)始使用的高級(jí) Python 庫(kù)有太多。因此,為了實(shí)際目標(biāo),你應(yīng)該記住以下這些:
- 數(shù)組(Array)——這與 R 的列表類似。它可以是多維的。它可以包含相同或多個(gè)類的數(shù)據(jù)。在多個(gè)類的情況下,會(huì)發(fā)生強(qiáng)制類型轉(zhuǎn)換。
- 列表(List)—— 相當(dāng)于 R 中的列表。
- 數(shù)據(jù)框(Data Frame)——它是一個(gè)包含多個(gè)列表的二維結(jié)構(gòu)。R中有內(nèi)置函數(shù) data.frame,Python則從 pandas庫(kù)中調(diào)用 Dataframe 函數(shù)。
- 矩陣(Matrix)——它是二維(或多維)結(jié)構(gòu),包含同一類(或多個(gè)類)的所有值。把矩陣看成是向量的二維版。在R中,我們使用 matrix 函數(shù)。在Python中,我們使用 numpy.column_stack 函數(shù)。
到這里,我希望你已經(jīng)明白了R和Python中數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)的基本知識(shí)。現(xiàn)在,讓我們開(kāi)始應(yīng)用它們。
用Python寫代碼(對(duì)比R)
我們現(xiàn)在來(lái)使用在前面部分學(xué)到的知識(shí),明白它們實(shí)際的含義。但在此之前,你要先通過(guò)Anaconda的 jupyter notebook 安裝 Python(之前稱為ipython notebook)。你可以點(diǎn)擊這里下載。我希望你已經(jīng)在電腦上安裝了 R Studio 。
創(chuàng)建列表
在 R 中,創(chuàng)建列表使用的是 list 函數(shù)
- my_list <- list ('monday','specter',24,TRUE)
- typeof(my_list)
- [1] "list"
在 Python 中,創(chuàng)建列表使用的是方括號(hào) [ ] 。
- my_list = ['monday','specter',24,True]
- type(my_list)
- list
在 pandas 庫(kù)中也可以得到相同的輸出,在 pandas 中,列表稱為序列。在 Python 中安裝 pandas,寫下:
- #importing pandas library as pd notation (you can use any notation) #調(diào)用 pandas 庫(kù)
- import pandas as pd
- pd_list = pd.Series(my_list)
- pd_list
- 0 monday
- 1 specter
- 2 24
- 3 True
數(shù)字(0,1,2,3)表示數(shù)組索引。你注意到什么了嗎?Python 索引是從 0 開(kāi)始,而 R 的索引從 1 開(kāi)始。讓我們繼續(xù)了解列表子集在 R 和 Python 的區(qū)別。
- #create a list # 創(chuàng)建一個(gè)列表
- new_list <- list(roll_number = 1:10, Start_Name = LETTERS[1:10])
把 new_list 看作一列火車。這列火車有兩個(gè)名為 roll_number 和 Start_Name 的車廂 。在每個(gè)車廂中,有10人。所以,在列表構(gòu)建子集中,我們可以提取車廂的值,車廂中的人等,等等。
- #extract first coach information #提取***個(gè)車廂信息
- new_list[1] #or
- df['roll_number']
- $roll_number
- [1] 1 2 3 4 5 6 7 8 9 10
- #extract only people sitting in first coach #提取坐在***個(gè)車廂中的人
- new_list[[1]] #or
- df$roll_number
- #[1] 1 2 3 4 5 6 7 8 9 10
如果你查詢一下 new_list [ 1 ] 的類型,你會(huì)發(fā)現(xiàn)它是一個(gè)列表,而 new_list [ [ 1 ] ] 類型是一個(gè)字符。類似地,在 Python 中,你可以提取列表組件:
- #create a new list #創(chuàng)建一個(gè)新列表
- new_list = pd.Series({'Roll_number' : range(1,10),
- 'Start_Name' : map(chr, range(65,70))})
- Roll_number [1, 2, 3, 4, 5, 6, 7, 8, 9]
- Start_Name [A, B, C, D, E]
- dtype: object
- #extracting first coach #提取***個(gè)車廂
- new_list[['Roll_number']] #or
- new_list[[0]]
- Roll_number [1, 2, 3, 4, 5, 6, 7, 8, 9]
- dtype: object
- #extract people sitting in first coach #提取坐在***個(gè)車廂中的人
- new_list['Roll_number'] #or
- new_list.Roll_number
- [1, 2, 3, 4, 5, 6, 7, 8, 9]
R 和 Python 的列表索引有一個(gè)讓人困惑的區(qū)別。如果你注意到在 R 中 [[ ]] 表示獲取車廂的元素, 然而[[ ]] 在 Python 中表示獲取車廂本身。
2. Matrix 矩陣
矩陣是由向量(或數(shù)組)組合而成的二維結(jié)構(gòu)。一般來(lái)說(shuō),矩陣包含同一類的元素。然而,即使你混合不同的類(字符串,布爾,數(shù)字等)中的元素,它仍會(huì)運(yùn)行。R 和 Python 在矩陣中構(gòu)建子集的方法很相似,除了索引編號(hào)。重申,Python 索引編號(hào)從 0 開(kāi)始,R 索引編號(hào)從 1 開(kāi)始。
在 R 中,矩陣可以這么創(chuàng)建:
- my_mat <- matrix(1:10,nrow = 5)
- my_mat
- #to select first row #選取***行
- my_mat[1,]
- #to select second column #選取第二列
- my_mat[,2]
在Python中,我們會(huì)借助 NumPy 數(shù)組創(chuàng)建一個(gè)矩陣。因此,我們先要加載 NumPy 庫(kù)。
- import numpy as np
- a=np.array(range(10,15))
- b=np.array(range(20,25))
- c=np.array(range(30,35))
- my_mat = np.column_stack([a,b,c])
- #to select first row #選取***行
- my_mat[0,]
- #to select second column #選取第二列
- my_mat[:,1]
3. 數(shù)據(jù)框(Data Frames)
數(shù)據(jù)框?yàn)閺亩鄟?lái)源收集而來(lái)的松散的數(shù)據(jù)提供了一個(gè)急需的骨架。它類似電子表格的結(jié)構(gòu)給數(shù)據(jù)科學(xué)工作者提供了一個(gè)很好的圖片來(lái)展示數(shù)據(jù)集是什么樣子。在R中,我們使用data.frame() 函數(shù)創(chuàng)建一個(gè)數(shù)據(jù)框。
- data_set <- data.frame(Name = c("Sam","Paul","Tracy","Peter"),
- Hair_Colour = c("Brown","White","Black","Black"),
- Score = c(45,89,34,39))
那么,我們知道一個(gè)數(shù)據(jù)框是由向量(列表)的組合創(chuàng)建的。在 Python 中創(chuàng)建數(shù)據(jù)框,我們將創(chuàng)建一個(gè)字典(數(shù)組的組合),并且在 pandas 庫(kù)的 Dataframe()函數(shù)中附上字典。
- data_set = pd.DataFrame({'Name' : ["Sam","Paul","Tracy","Peter"],
- 'Hair_Colour' : ["Brown","White","Black","Black"],
- 'Score' : [45,89,34,39]})
現(xiàn)在,讓我們看下操作 dataframe 最關(guān)鍵的部分,構(gòu)建子集。實(shí)際上,大部分?jǐn)?shù)據(jù)操作都包含從各個(gè)可能的角度切割數(shù)據(jù)框。讓我們逐個(gè)看下任務(wù):
- #select first column in R #在 R 中選取***行
- data_set$Name # or
- data_set[["Name]] #or
- data_set[1]
- #select first column in Python #在 Python 中選取***列
- data_set['Name'] #or
- data_set.Name #or
- data_set[[0]]
- #select multiple columns in R # 在 R 中選取多列
- data_set[c('Name','Hair_Colour')] #or
- data_set[,c('Name','Hair_Colour')]
- #select multiple columns in Python #在 Python 中選取多行
- data_set[['Name','Hair_Colour']] #or
- data_set.loc[:,['Name','Hair_Colour']]
.loc 函數(shù)用于基于標(biāo)簽的索引
到這里我們大致明白了 R 和 Python 中的數(shù)據(jù)類型、結(jié)構(gòu)和格式。讓我們用一個(gè)數(shù)據(jù)集來(lái)探索 python 中數(shù)據(jù)的其他面。
用一個(gè)數(shù)據(jù)集實(shí)踐 Python
強(qiáng)大的 scikit-learn 庫(kù)包含一個(gè)內(nèi)建的數(shù)據(jù)集庫(kù)。為了我們實(shí)踐的目的,我們將采用波士頓住房數(shù)據(jù)集(Boston housing data set)。做數(shù)據(jù)分析時(shí),它是一個(gè)很流行的數(shù)據(jù)集。
- #import libraries #調(diào)用庫(kù)
- import numpy as np
- import pandas as pd
- from sklearn.datasets import load_boston
- #store in a variable #存儲(chǔ)在一個(gè)變量中
- boston = load_boston()
變量boston是一個(gè)字典?;仡櫼幌?,字典是key-value對(duì)的組合,讓我看下鍵(key)的信息:
- boston.keys()
- ['data', 'feature_names', 'DESCR', 'target']
現(xiàn)在我們知道我們需要的數(shù)據(jù)集駐留在key數(shù)據(jù)中。我們也看到,對(duì)于功能名稱有一個(gè)單獨(dú)的key。我認(rèn)為數(shù)據(jù)集不會(huì)分配列名。讓我們來(lái)檢查下我們要處理的列名。
- print(boston['feature_names'])
- ['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO' 'B' 'LSTAT']
你能明白這些名稱嗎?我也不明白?,F(xiàn)在,讓我們檢查下數(shù)據(jù)描述和理解每個(gè)變量的意義。
- print(boston['DESCR'])
這個(gè)數(shù)據(jù)集有506行,13列。它包含幫助確定波士頓房?jī)r(jià)的多種特征。現(xiàn)在,讓我們創(chuàng)建一個(gè)數(shù)據(jù)框:
- bos_data = pd.DataFrame(boston['data'])
類似于 R , python 也有一個(gè) head()函數(shù)讀入數(shù)據(jù):
- bos_data.head()
輸出顯示數(shù)據(jù)集沒(méi)有列名(如上所述)。將列名分配到數(shù)據(jù)框中是容易的。
- bos_data.columns = boston['feature_names']
- bos_data.head()
就像R中的 dim() 函數(shù),Python 有檢查數(shù)據(jù)集維數(shù)的 shape() 函數(shù)。為得到數(shù)據(jù)集的統(tǒng)計(jì)匯總,我們寫下:
- bos_data.describe()
它顯示了數(shù)據(jù)中列的統(tǒng)計(jì)匯總。讓我們快速探索這個(gè)數(shù)據(jù)的其他方面。
- #get first 10 rows #得到***10行
- bos_data.iloc[:10]
- #select first 5 columns #選取***個(gè)5列
- bos_data.loc[:,'CRIM':'NOX'] #or
- bos_data.iloc[:,:5]
- #filter columns based on a condition #基于條件篩選列
- bos_data.query("CRIM > 0.05 & CHAS == 0")
- #sample the data set #構(gòu)建數(shù)據(jù)集樣本
- bos_data.sample(n=10)
- #sort values - default is ascending #分類上升的默認(rèn)值
- bos_data.sort_values(['CRIM']).head() #or
- bos_data.sort_values(['CRIM'],ascending=False).head()
- #rename a column #重命名一個(gè)列
- bos_data.rename(columns={'CRIM' : 'CRIM_NEW'})
- #find mean of selected columns #查找選定列的平均值
- bos_data[['ZN','RM']].mean()
- #transform a numeric data into categorical #將數(shù)字?jǐn)?shù)據(jù)轉(zhuǎn)換成分類
- bos_data['ZN_Cat'] = pd.cut(bos_data['ZN'],bins=5,labels=['a','b','c','d','e'])
- #calculate the mean age for ZN_Cat variable #計(jì)算ZN_Cat變量的平均年齡
- bos_data.groupby('ZN_Cat')['AGE'].sum()
此外,Python 還允許我們創(chuàng)建透視表。是的! 就像 MS Excel 或任何其他電子表格軟件,你可以創(chuàng)建一個(gè)數(shù)據(jù)透視表,更密切地了解數(shù)據(jù)。不幸的是,在 R 中創(chuàng)建一個(gè)數(shù)據(jù)透視表是一個(gè)相當(dāng)復(fù)雜的過(guò)程。在 Python 中,一個(gè)透視表需要行名、列名和要計(jì)算的值。如果我們不通過(guò)任何列名稱,得到的結(jié)果只會(huì)像你使用 groupby 函數(shù)得到的。因此,讓我們創(chuàng)建另一個(gè)分類變量。
- #create a new categorical variable #創(chuàng)建一個(gè)新的分類變量
- bos_data['NEW_AGE'] = pd.cut(bos_data['AGE'],bins=3,labels=['Young','Old','Very_Old'])
- #create a pivot table calculating mean age per ZN_Cat variable #創(chuàng)建一個(gè)透視表計(jì)算每個(gè) ZN_Cat 變量的年齡
- bos_data.pivot_table(values='DIS',index='ZN_Cat',columns= 'NEW_AGE',aggfunc='mean')
這只是冰山一角。下一步怎么做?就像我們使用波士頓住房數(shù)據(jù)集,現(xiàn)在你可以試試安德森鳶尾花卉數(shù)據(jù)集(iris data)。它在sklearn_datasets 庫(kù)是可用的。嘗試深入探討。記住,你練習(xí)越多,花費(fèi)的時(shí)間越多,你就會(huì)變得越好。
總結(jié)
總體來(lái)說(shuō),學(xué)習(xí)這兩門語(yǔ)言會(huì)給你足夠的自信去處理任何類型的數(shù)據(jù)集。事實(shí)上,學(xué)習(xí)python***的一面是它有完善的文檔可以用在numpy,pandas,scikit learn 庫(kù),這足夠幫你跨越所有最初的障礙。