左手用R右手Python系列——因子變數與分類重編碼

今天這篇介紹數據類型中因子變數的運用在R語言和Python中的實現。

因子變數是數據結構中用於描述分類事物的一類重要變數。其在現實生活中對應著大量具有實際意義的分類事物。

比如年齡段、性別、職位、愛好,星座等。

之所以給其單獨列出一個篇幅進行講解,除了其在數據結構中的特殊地位之外,在數據可視化和數據分析與建模過程中,因子變數往往也承擔中描述某一事物重要維度特徵的作用,其意義非同尋常,無論是在數據處理過程中還是後期的分析與建模,都不容忽視。

通常意義上,按照其所描述的維度實際意義,因子變數一般又可細分為無序因子(類別之間沒有特定順序,水平相等)和有序因子(類別中間存在某種約定俗成的順序,如年齡段、職稱、學歷、體重等)。

在統計學中對變數進行了如下四類劃分:定類變數、定序變數、定距變數、定比變數。而其中的定類和定比變數就對應著我們今天將要講解的因子變數(無序因子和有序因子變數)。

因子變數從信息含量上來看,其要比單純的定性變數(文本變數)所包含的描述信息多一些,但是又比數值型變數(定距變數和定比變數)所表述的信息含量少一些。

因而原則上來講,數值型變數可以轉換為因子變數,因子變數可以轉換為文本型變數,但是以上順序卻是不可逆的(信息含量多的變數可以放棄信息量,轉換為信息含量較少的變數類型,但是信息含量較少的變數卻無法增加信息含量)。

以下將分別講解在R語言和Python中如何生成因子變數、如何將數值型變數轉換為因子變數、以及如何對因子變數進行重編碼。

在R語言中,通常使用factor直接生成因子變數,我們僅需一個向量(原則上可以是文本型、也可以是數字型,但是通常從實際意義上來說,被轉換的應該是一個含有多類別的類別型文本變數)。

factor(x, levels,labels=levels,ordered=)

以上參數中,x即是我們將要轉換的變數,levels是將要設定的因子水平(可選參數,省略則自動以向量中的不重複對象為因子水平),labels作為因子標籤(可選參數,與前述因子水平對應,若設置,則列印時顯示的是對應因子標籤,省略則同因子水平一樣,使用向量中不重複值【即類別】作為標籤),ordered是邏輯參數,設定是否對因子水平排序。

vector<-rep(LETTERS[1:5],6);print(vector);plyr::count(vector)myfactor<-(factor(vector,levels=c("E","D","C","B","A"),labels=c("EEE","DDD","CCC","BBB","AAA"),ordered=TRUE)

通常來說,factor函數中,levels一般不用設置,函數會自動判斷向量內有幾個水平,但是倘若要生成有序因子的話,默認會根據字母順序排列,如果自然順序與目標有序因子順序不一致,則一定要指定levels,labels則視具體需求而定,如果本身就是文本類別的話,一般無需設定標籤。

如果是問卷類數據,而且編碼為數值,則一定要通過labels標籤的設定來還原每一個編碼的真實意義。

factor(vector,labels=c("AAA","BBB","CCC","DDD","EEE"),ordered=TRUE)

因子變數與文本變數數值變數之間的互轉則通過as.character()或者as.numeric()函數來實現。

library(dplyr)as.character(as.factor(1:10))%>%str()as.numeric(as.factor(1:10))%>%str()

R語言中的因子變數重編碼

如果你有一個度量指標,需要將其轉換為分段的因子變數,則可以通過cut函數來實現這種轉換。

scale<-runif(100,0,100)cut(x,breaks,labels=NULL,include.lowest=FALSE,right=TRUE,ordered=)

cut函數參數如上,接受一個數值型向量,breaks接受一個數值向量(標識分割點)或者單個數值(分割 數目)。

right是邏輯參數,設定分割帶是左開右閉或者左閉右開。(默認左開右閉)。

include.lowest則根據right的設定,決定是否應該包含端點值(如果right為TRUE,左開右閉區間,則包含最小值,如果right為FALSE,左閉右開區間則包含最大值),默認為FALSE。

ordered則設定是否對因子水平進行排序。

(factor1<-cut(scale,breaks=c(0,20,40,60,80,100),labels=c("0~20","20~40","40~60","60~80","80~100"),include.lowest=TRUE,ordered=TRUE)

另一種分割場景是使用分位數函數進行分割。

qa <- quantile(scale, c(0,0.2,0.4,0.6,0.8,1.0))(cut(scale,breaks=qa,labels=c("0%~20%","20%~40%","40%~60%","60%~80%","80%~100%"),include.lowest=TRUE,ordered=TRUE))

以上分割方法在是較為常用的因子變數轉換方法,當然你可以使用if函數進行類似分割,但是相比較來講,使用cut函數進行分割要高效很多。

Python

在Python中,Pandas庫包含了處理因子變數的一整套完整語法函數。

import pandas as pdimport numpy as npimport string

在pandas中的官方在線文檔中,給出了pandas因子變數的詳細論述,並在適當位置與R語言進行了對比描述。

pandas.pydata.org/panda

當利用pandas生成序列時,可以在序列函數內的dtype參數設定因子變數類型。

s = pd.Series(["A","B","C","D","E"], dtype="category")

生成數據框時,也可以直接生成因子變數。

df = pd.DataFrame({"A":["a","b","c","a"]})df["B"] = df["A"].astype("category")

除了直接在生成序列或者數據框時生成因子變數之外,也可以通過一個特殊的函數pd.Categorical來完成在序列和數據框中創建因子變數。

s = pd.Series(pd.Categorical(["a","b","c","a"], categories=["a","b","c"],ordered=False))df = pd.DataFrame({"A":["a","b","c","a"]})df["B"] =pd.Series(pd.Categorical(["a","b","c","a"], categories=["a","b","c"],ordered=False))

因子順序的添加可以通過設定序列或者數框框列的.astype來進行詳細的操作。

s = pd.Series(["a","b","c","a"])s_cat = s.astype("category", categories=["a","b","c"], ordered=True)

無論是序列中還是數據框中的因子變數生成之後,都可以通過以下屬性查看其具體的類型、因子類別、以及是否含有順序。

  • s_cat.dtypes
  • s_cat.cat.categories
  • s_cat.cat.ordered

一種比較迂迴的方法是,先生成普通序列,然後通過設定序列類型完成因子變數的轉化。而想要捨棄因子變數,還原成普通的文本序列,則同樣只需再其astype中進行格式設定。

s = pd.Series(["a","b","c","a"])s2 = s.astype("category",categories=["a","b","c"],ordered=True)s2.astype(str)

最後講一下,如何在數據框中分割數值型變數為因子變數,pandas的數據框也有與R語言同名的函數——cut

df = pd.DataFrame({"value": np.random.randint(0, 100, 20)})labels = [ "{0} - {1}".format(i, i + 9) for i in range(0,100,10) ]df["group"] = pd.cut(df.value, range(0, 105, 10), right=False, labels=labels)

pd.cut(x, bins, right=, labels=,include_lowest=False)#df.value代表待風格的變數,第二項是bins可以是一個列表(作為分割點),也可以是一個整數(作為分割帶箱數),right控制帶寬是左開右閉還是左閉右開,labels設定輸出顯示標籤,include_lowest=控制是否包含邊界點(以上參數可以類比R語言中的cut函數)。

最後做一個小總結:

關於因子變數在R語言和Python中涉及到的操作函數;

R語言:

創建因子變數:

factor

轉換因子變數:

as.factor

as.numeric(as.character)

分割因子變數:

cut函數

Python:

創建因子變數:

pd.Categorical(categories=,ordered=)

pd.Series(dtype="category")

轉換因子變數:

df.astype("category",categories,ordered)

分割因子變數:

df.cut(df.value,breaks=,right=,labels)

微信:ljty1991

博客主頁:raindu&#x27;s home

個人公眾號:數據小魔方(datamofang)

團隊公眾號:EasyCharts

qq交流群:[魔方學院]298236508

推薦閱讀:

R for data science之purrr包(上)
BI轉數據挖掘,我的脫產學習路
七周成為數據分析師:Excel技巧:好用到哭的多級菜單
YARN 分散式資源調度
人工智慧和機器學習會逐漸取代金融和數據分析師嗎?

TAG:R编程语言 | Python | 数据分析师 |