數據分析入門之pandas數據預處理

1、合併數據

導入數據:

import pandas as pd
from sqlalchemy import create_engine

engin = create_engine('mysql+pymysql://root:123456@localhost:3306/test?charset=utf8')
data = pd.read_sql('meal_order_detail1', con=engin)

在這裏插入圖片描述

1.1、橫向表堆疊

  • 橫向堆疊,即將兩個表在X軸向拼接在一起,可以使用concat函數完成,concat函數的基本語法如下:
  • pandas.concat(objs, axis=0, join=‘outer’, join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)
  • 常用參數如下所示:
參數名稱 說明
objs 接收多個Series,DataFrame,Panel的組合。表示參與鏈接的pandas對象的列表的組合。無默認
axis 接收0或1。表示連接的軸向,默認爲0
join 接收inner或outer。表示其他軸向上的索引是按交集(inner)還是並集(outer)進行合併。默認爲outer
join_axes 接收Index對象。表示用於其他n-1條軸的索引,不執行並集/交集運算
ignore_index 接收boolean。表示是否不保留連接軸上的索引,產生一組新索引range(total_length)。默認爲False
keys 接收sequence。表示與連接對象有關的值,用於形成連接軸向上的層次化索引。默認爲None
levels 接收包含多個sequence的list。表示在指定keys參數後,指定用作層次化索引各級別上的索引。默認爲None
names 接收list。表示在設置了keys和levels參數後,用於創建分層級別的名稱。默認爲None
verify_integrity 接收boolearn。表示是否檢查結果對象新軸上的重複情況,如果發現則引發異常。默認爲False
  • 當axis=1的時候,concat做行對齊,然後將不同列名稱的兩張或多張表合併。當兩個表索引不完全一樣時,可以使用join參數選擇是內連接還是外連接。在內連接的情況下,僅僅返回索引重疊部分。在外連接的情況下,則顯示索引的並集部分數據,不足的地方則使用空值填補。

在這裏插入圖片描述

  • 當兩張表完全一樣時,不論join參數取值是inner或者outer,結果都是將兩個表完全按照X軸拼接起來。
a = data.iloc[:,:10]#所有行的前10列數據,按位置索引
b = data.iloc[:,10:]#所有行的10列後數據
pdcc = pd.concat([a,b], axis=1)#合併完成,axis=1表示橫向,左右拼接
pdcc.shape

理解: data.iloc[:,:5] [縱 : 橫],縱向全選,橫向選5個截至。

在這裏插入圖片描述

1.2、縱向堆疊

1.2.1、concat函數

  • 使用concat函數時,在默認情況下,即axis=0時,concat做列對齊,將不同行索引的兩張或多張表縱向合併。在兩張表的列名並不完全相同的情況下,可join參數取值爲inner時,返回的僅僅是列名交集所代表的列,取值爲outer時,返回的是兩者列名的並集所代表的列,其原理示意如圖:
    在這裏插入圖片描述
  • 不論join參數取值是inner或者outer,結果都是將兩個表完全按照Y軸拼接起來。
a = data.iloc[:100,:]
b = data.iloc[100:,:]
pd.concat([a,b]).shape#axis=0,默認可以不寫
(2779, 19)

1.2.2、append方法

  • append方法也可以用於縱向合併兩張表。但是append方法實現縱向表堆疊有一個前提條件,那就是兩張表的列名需要完全一致
  • pandas.DataFrame.append(self, other, ignore_index=False, verify_integrity=False)
  • 常用參數如下所示:
參數名稱 說明
other 接收DataFrame或Series。表示要添加的新數據。無默認
ignore_index 接收boolean。如果輸入True,會對新生成的DataFrame使用新的索引(自動產生)而忽略原來數據的索引。默認爲False
verify_integrity 接收boolean。如果輸入True,那麼當ignore_index爲False時,會檢查添加的數據索引是否衝突,如果衝突,則會添加失敗。默認爲False
a.append(b).shape
(2779, 19)

1.3、主鍵合併數據

(1) 導入數據

order = pd.read_csv('./meal_order_info.csv',encoding='gbk')
order.head()

在這裏插入圖片描述
(2) 查看數據類型
在這裏插入圖片描述
(3) 轉換數據類型

order['info_id'] = order['info_id'].astype(str)

1.3.1、merge函數

pd.merge(order, data, left_on='info_id', right_on='order_id')

在這裏插入圖片描述

1.3.2、join方法

  • join方法也可以實現部分主鍵合併的功能,但是join方法使用時,兩個主鍵的名字必須相同
  • pandas.DataFrame.join(self, other, on=None, how=‘left’, lsuffix=’’, rsuffix=’’, sort=False)
  • 常用參數說明如下:
參數名稱 說明
other 接收DataFrame、Series或者包含了多個DataFrame的list。表示參與連接的其他DataFrame。無默認
on 接收列名或者包含列名的list或tuple。表示用於連接的列名。默認爲None
how 接收特定string。inner代表內連接;outer代表外連接;left和right分別代表左連接和右連接。默認爲inner
rsuffix 接收string。表示用於追加到右側重疊列名的末尾。無默認
lsuffix 接收sring。表示用於追加到左側重疊列名的末尾。無默認
sort 根據連接鍵對合並後的數據進行排序,默認爲True

(1)更改order的主鍵名稱

order.rename(columns={'info_id':'order_id'},inplace=True)

在這裏插入圖片描述
(2)按主鍵合併數據

data.join(order, on='order_id', rsuffix='1')

1.4、重疊合並數據

  • 數據分析和處理過程中若出現兩份數據的內容幾乎一致的情況,但是某些特徵在其中一張表上是完整的,而在另外一張表上的數據則是缺失的時候,可以用combine_first方法進行重疊數據合併,其原理如下:
    在這裏插入圖片描述
    combine_first方法
  • combine_first的具體用法如下:
  • pandas.DataFrame.combine_first(other)
  • 參數及其說明如下:
參數名稱 說明
other 接收DataFrame。表示參與重疊合並的另一個DataFrame。無默認

(1) 構造兩個數組

import numpy as np

dis1 = {
    'id':list(range(1,10)),
    'cpu':['i7', 'i5', np.nan, 'i7', 'i7', 'i5', np.nan, np.nan,'i5']
}
a = pd.DataFrame(dis1)

dis2 = {
    'id':list(range(1,10)),
    'cpu':['i7', 'i5', 'i5', np.nan, 'i7', 'i5', 'i5', np.nan,'i5']
}
b = pd.DataFrame(dis2)

在這裏插入圖片描述
(2) 缺失值合併

a.combine_first(b)

在這裏插入圖片描述



2、清洗數據

2.1、檢測與處理重複值

2.1.1、記錄重複

  • 記錄重複,即一個或者多個特徵某幾個記錄的值完全相同

2.1.1.1、利用列表(list)去重

def delRep(list1):
    list2=[]
    for i in list1:
        if i not in list2:
            list2.append(i)
    return list2 

2.1.1.2、利用集合(set)的元素是唯一的特性去重

dish_set = set(dishes)

比較上述兩種方法可以發現,方法一代碼冗長。方法二代碼簡單了許多,但會導致數據的排列發生改變。

2.1.1.3、drop_duplicates去重方法

  • pandas提供了一個名爲drop_duplicates的去重方法。該方法只對DataFrame或者Series類型有效。這種方法不會改變數據原始排列,並且兼具代碼簡潔和運行穩定的特點。該方法不僅支持單一特徵的數據去重,還能夠依據DataFrame的其中一個或者幾個特徵進行去重操作。
  • pandas.DataFrame(Series).drop_duplicates(self, subset=None, keep=‘first’, inplace=False)
參數名稱 說明
subset 接收string或sequence。表示進行去重的列。默認爲None,表示全部列
keep 接收特定string。表示重複時保留第幾個數據。First:保留第一個。Last:保留最後一個。False:只要有重複都不保留。默認爲first
inplace 接收boolean。表示是否在原表上進行操作。默認爲False

(1) 查看數據

data['dishes_name']
0         蒜蓉生蠔
1        蒙古烤羊腿
2         大蒜莧菜
3        芝麻烤紫菜
4          蒜香包
         ...  
2774     白飯/大碗
2775       牛尾湯
2776    意文檸檬汁 
2777      金玉良緣
2778      酸辣藕丁
Name: dishes_name, Length: 2779, dtype: object

(2) 數據單列去重

data['dishes_name'].drop_duplicates()
0             蒜蓉生蠔
1            蒙古烤羊腿
2             大蒜莧菜
3            芝麻烤紫菜
4              蒜香包
           ...    
1024        海帶結豆腐湯
1169          冰鎮花螺
1411         冬瓜炒苦瓜
1659       超人氣廣式腸粉
2438    百里香奶油烤紅酒牛肉
Name: dishes_name, Length: 145, dtype: object

(3) 數據整體去重

data.drop_duplicates().shape
(2779, 19)

(4) 數據並列去重

data.drop_duplicates(subset=['order_id','emp_id']).shape
(278, 19)

2.1.2、特徵重複

2.1.2.1、corr函數

  • 結合相關的數學和統計學知識,去除連續型特徵重複可以利用特徵間的相似度將兩個相似度爲1的特徵去除一個。在pandas中相似度的計算方法爲corr,使用該方法計算相似度時,默認爲“pearson”法 ,可以通過“method”參數調節,目前還支持“spearman”法和“kendall”法。
data[['counts','amounts']].corr()

在這裏插入圖片描述

  • 但是通過相似度矩陣去重存在一個弊端,該方法只能對數值型重複特徵去重,類別型特徵之間無法通過計算相似係數來衡量相似度。

2.1.2.2、DataFrame.equals()函數

sim_dis = pd.DataFrame([],
                       index=['counts','amounts','dishes_name'],
                      columns=['counts','amounts','dishes_name'])
for i in ['counts','amounts','dishes_name']:
    for j in ['counts','amounts','dishes_name']:
        sim_dis.loc[i,j] = data[i].equals(data[j])
print (sim_dis)
             counts  amounts  dishes_name
counts         True    False        False
amounts       False     True        False
dishes_name   False    False         True

2.1、檢測與處理缺失值

2.1.1、缺失值檢測——利用isnull或notnull找到缺失值

  • 數據中的某個或某些特徵的值是不完整的,這些值稱爲缺失值。
  • pandas提供了識別缺失值的方法isnull以及識別非缺失值的方法notnull,這兩種方法在使用時返回的都是布爾值True和False。
  • 結合sum函數和isnull、notnull函數,可以檢測數據中缺失值的分佈以及數據中一共含有多少缺失值。
  • isnull和notnull之間結果正好相反,因此使用其中任意一個都可以判斷出數據中缺失值的位置。
data.isnull()

在這裏插入圖片描述

  • 它們返回的數值都是一樣的,所以它們的數據都不存在空值,平時只需要使用一個就可以判斷了。
    在這裏插入圖片描述

2.1.2、處理缺失值

dis1 = {
    'id':list(range(1,10)),
    'cpu':['i7', 'i5', np.nan, 'i7', 'i7', 'i5', np.nan, np.nan,'i5']
}
a = pd.DataFrame(dis1)

在這裏插入圖片描述

2.1.2.1、刪除法

  • 刪除法分爲刪除觀測記錄和刪除特徵兩種,它屬於利用減少樣本量來換取信息完整度的一種方法,是一種最簡單的缺失值處理方法。

  • pandas中提供了簡便的刪除缺失值的方法dropna,該方法既可以刪除觀測記錄,亦可以刪除特徵。

  • pandas.DataFrame.dropna(self, axis=0, how=‘any’, thresh=None, subset=None, inplace=False)

  • 常用參數及其說明如下:

參數名稱 說明
axis 接收0或1。表示軸向,0爲刪除觀測記錄(行),1爲刪除特徵(列)。默認爲0
how 接收特定string。表示刪除的形式。any表示只要有缺失值存在就執行刪除操作。all表示當且僅當全部爲缺失值時執行刪除操作。默認爲any
subset 接收類array數據。表示進行去重的列∕行。默認爲None,表示所有列/行
inplace 接收boolean。表示是否在原表上進行操作。默認爲False
#默認橫向刪除
a.dropna()

#刪除指定列缺失數據
a.dropna(subset=['id'])

#刪除缺失的列
a.dropna(axis=1)

在這裏插入圖片描述
注意: 這樣刪除缺失值並不會對原數據造成影響,需要變化的話可以加上inplace=True。

2.1.2.2、替換法

  • 替換法是指用一個特定的值替換缺失值。
  • 特徵可分爲數值型和類別型,兩者出現缺失值時的處理方法也是不同的。
    • 缺失值所在特徵爲數值型時,通常利用其均值、中位數和衆數等描述其集中趨勢的統計量來代替缺失值。
    • 缺失值所在特徵爲類別型時,則選擇使用衆數來替換缺失值。
  • pandas庫中提供了缺失值替換的方法名爲fillna,其基本語法如下:
  • pandas.DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None)
參數名稱 說明
value 接收scalar,dict,Series或者DataFrame。表示用來替換缺失值的值。無默認
method 接收特定string。backfill或bfill表示使用下一個非缺失值填補缺失值。pad或ffill表示使用上一個非缺失值填補缺失值。默認爲None
axis 接收0或1。表示軸向。默認爲1
inplace 接收boolean。表示是否在原表上進行操作。默認爲False
limit 接收int。表示填補缺失值個數上限,超過則不進行填補。默認爲None

(1) 指定替換爲某值

a['cpu'].fillna('i7')

在這裏插入圖片描述
(2) 查看衆數
在這裏插入圖片描述
(3) 利用衆數填充

a['cpu'].fillna(a['cpu'].value_counts().index[0])
0    i7
1    i5
2    i7
3    i7
4    i7
5    i5
6    i7
7    i7
8    i5
Name: cpu, dtype: obje

(4) 利用均值替換

  • 夠着一個數值型數組
import numpy as np

dis1 = {
    'id':list(range(1,10)),
    'num':[7, 7, np.nan, 5, 4, 6, np.nan, np.nan,7]
}
a = pd.DataFrame(dis1)
a

在這裏插入圖片描述

a['num'].fillna(a['num'].mean())
0    7.0
1    7.0
2    6.0
3    5.0
4    4.0
5    6.0
6    6.0
7    6.0
8    7.0
Name: num, dtype: float64

(5) 插值法

  • 刪除法簡單易行,但是會引起數據結構變動,樣本減少;替換法使用難度較低,但是會影響數據的標準差,導致信息量變動。在面對數據缺失問題時,除了這兩種方法之外,還有一種常用的方法—插值法.

  • 常用的插值法有線性插值、多項式插值和樣條插值等:

    • 線性插值是一種較爲簡單的插值方法,它針對已知的值求出線性方程,通過求解線性方程得到缺失值。
    • 多項式插值是利用已知的值擬合一個多項式,使得現有的數據滿足這個多項式,再利用這個多項式求解缺失值,常見的多項式插值法有拉格朗日插值和牛頓插值等。
    • 樣條插值是以可變樣條來作出一條經過一系列點的光滑曲線的插值方法,插值樣條由一些多項式組成,每一個多項式都是由相鄰兩個數據點決定,這樣可以保證兩個相鄰多項式及其導數在連接處連續。
  • 從擬合結果可以看出多項式插值和樣條插值在兩種情況下擬合都非常出色,線性插值法只在自變量和因變量爲線性關係的情況下擬合才較爲出色。

  • 而在實際分析過程中,自變量與因變量的關係是線性的情況非常少見,所以在大多數情況下,多項式插值和樣條插值是較爲合適的選擇。

  • SciPy庫中的interpolate模塊除了提供常規的插值法外,還提供了例如在圖形學領域具有重要作用的重心座標插值(BarycentricInterpolator)等。在實際應用中,需要根據不同的場景,選擇合適的插值方法。

線性插值法:

x = np.array([1,2,3,6,7])
y = np.array([3,5,6,9,13])
from scipy.interpolate import interp1d
model = interp1d(x,y,kind='linear')
model([4,5])

結果:

array([7., 8.])
  • 數據可視化表示
import matplotlib.pyplot as plt
plt.scatter(x,y)#藍色的點
plt.plot(x, model(x),'r-')#插值後紅色的線
plt.show()

在這裏插入圖片描述

拉格朗日插值法:

from scipy.interpolate import lagrange
f_lag = lagrange(x,y)
f_lag([4,5])

結果:

array([6.5, 7.2])

數據可視化:

import matplotlib.pyplot as plt

plt.scatter(x,y)#藍色的點表示原數據

plt.plot(x, y,'c-')#淺綠色的線表示原數據

plt.scatter([4,5],model([4,5]),c='r')#紅點表示線性插值點

plt.scatter([4,5],f_lag([4,5]),c='b')#紅點表示拉格朗日插值點

#支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號
plt.legend(['原點','原線','線性插值','拉格朗日插值'])

plt.show()

在這裏插入圖片描述
樣條插值法:

from scipy.interpolate import BSpline
y_bs = BSpline(x, y, k=1)
y_bs([4,5])
array([5.33333333, 5.66666667])

2.2、檢測與處理異常值

2.2.1、異常值

  • 異常值是指數據中個別值的數值明顯偏離其餘的數值,有時也稱爲離羣點,檢測異常值就是檢驗數據中是否有錄入錯誤以及是否含有不合理的數據。
  • 異常值的存在對數據分析十分危險,如果計算分析過程的數據有異常值,那麼會對結果會產生不良影響,從而導致分析結果產生偏差乃至錯誤。
  • 常用的異常值檢測主要爲3σ原則和箱線圖分析兩種方法。

2.2.2、3σ原則

  • 3σ原則又稱爲拉依達法則。該法則就是先假設一組檢測數據只含有隨機誤差,對原始數據進行計算處理得到標準差,然後按一定的概率確定一個區間,認爲誤差超過這個區間的就屬於異常值。
  • 這種判別處理方法僅適用於對正態或近似正態分佈的樣本數據進行處理,如下表所示,其中σ代表標準差,μ代表均值,x=μ爲圖形的對稱軸。
  • 數據的數值分佈幾乎全部集中在區間(μ-3σ,μ+3σ)內,超出這個範圍的數據僅佔不到0.3%。故根據小概率原理,可以認爲超出3σ的部分數據爲異常數據。
    在這裏插入圖片描述
u = data['counts'].mean()
o = data['counts'].std()
index = data['counts'].apply(lambda x: x > u+3*o or x < u-3*o)#遍歷查詢(u-3*o,u+3*o)之外的數據,返回True和False
data.loc[index,'counts']#索引出異常值
94      5.0
176     3.0
238     4.0
270     4.0
346     4.0
       ... 
2370    3.0
2458    3.0
2459    4.0
2461    6.0
2501    7.0
Name: counts, Length: 62, dtype: float64

2.2.3、箱線圖分析

  • 箱型圖提供了識別異常值的一個標準,即異常值通常被定義爲小於QL-1.5IQR或大於QU+1.5IQR的值。
    • QL稱爲下四分位數,表示全部觀察值中有四分之一的數據取值比它小。
    • QU稱爲上四分位數,表示全部觀察值中有四分之一的數據取值比它大。
    • IQR稱爲四分位數間距,是上四分位數QU與下四分位數QL之差,其間包含了全部觀察值的一半。
  • 箱線圖依據實際數據繪製,真實、直觀地表現出了數據分佈的本來面貌,且沒有對數據做任何限制性要求,其判斷異常值的標準以四分位數和四分位數間距爲基礎。
  • 四分位數給出了數據分佈的中心、散佈和形狀的某種指示,具有一定的魯棒性,即25%的數據可以變得任意遠而不會很大地擾動四分位數,所以異常值通常不能對這個標準施加影響。鑑於此,箱線圖識別異常值的結果比較客觀,因此在識別異常值方面具有一定的優越性。

(1)箱線圖分析

import matplotlib.pyplot as plt
plt.boxplot(data['counts'])
plt.show()

在這裏插入圖片描述

  • 上圖表明:data[‘counts’]的數據大多數都在1上,上面出現的黑圈爲異常值,實際爲用戶點餐超過1份的客戶。

(2)取出異常值

p = plt.boxplot(data['counts'])
p['fliers'][0].get_ydata()
array([ 2.,  2.,  2.,  2.,  5.,  2.,  2.,  2.,  2.,  2.,  3.,  2.,  2.,
        2.,  2.,  4.,  2.,  4.,  4.,  4.,  2.,  4., 10.,  4.,  6.,  2.,
        6.,  6.,  8.,  2.,  2.,  2.,  6.,  6.,  4.,  3.,  4.,  6.,  2.,
        6.,  6.,  2.,  8.,  3.,  2.,  2.,  2.,  4.,  2.,  2.,  2.,  2.,
        3.,  6.,  8.,  2.,  2.,  2.,  2.,  5.,  2.,  2.,  5.,  3.,  4.,
        2.,  3.,  2.,  2.,  4.,  8.,  2.,  2.,  3.,  3.,  2.,  2.,  2.,
        4.,  4.,  2.,  2.,  2.,  4.,  6.,  2.,  3.,  3.,  3.,  2.,  2.,
        2.,  2.,  2.,  2.,  3.,  2.,  3.,  3.,  2.,  3.,  2.,  4.,  6.,
        2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  4.,  7.,  2.,
        2.,  4.,  8.,  8.,  4.,  3.,  3.,  3.,  2.,  2.,  2.,  2.,  2.,
        2.,  3.,  4.,  6.,  7.,  2.,  2.,  2.,  2.,  2.,  2.])


3、標準化數據

3.1、離差標準化數據

導入數據:

import pandas as pd
data = pd.read_csv('./detail.csv', encoding='gbk')
data.head()

在這裏插入圖片描述

3.1.1、離差標準化公式

在這裏插入圖片描述

def MinMaxScale(data):
    return (data - data.min()) / (data.max()-data.min())
a = MinMaxScale(data['counts'])
b = MinMaxScale(data['amounts'])
pd.concat([a,b],axis=1)

在這裏插入圖片描述

3.1.2、離差標準化的特點

  • 數據的整體分佈情況並不會隨離差標準化而發生改變,原先取值較大的數據,在做完離差標準化後的值依舊較大。
  • 當數據和最小值相等的時候,通過離差標準化可以發現數據變爲0。
  • 若數據極差過大就會出現數據在離差標準化後數據之間的差值非常小的情況。
  • 同時,還可以看出離差標準化的缺點:若數據集中某個數值很大,則離差標準化的值就會接近於0,並且相互之間差別不大。若將來遇到超過目前屬性[min,max]取值範圍的時候,會引起系統出錯,這時便需要重新確定min和max。

3.2、標準差標準化數據

標準差標準化的公式及特點
在這裏插入圖片描述

def StandScale(data):
    return (data - data.mean()) / data.std()
a = StandScale(data['counts'])
b = StandScale(data['amounts'])
pd.concat([a,b],axis=1)

在這裏插入圖片描述

3.3、小數定標標準化數據

小數定標標準化公式及對比:
在這裏插入圖片描述

import numpy as np
def DecimalScale(data):
    return data / 10**(np.ceil(data.abs().max()))
a = DecimalScale(data['counts'])
b = DecimalScale(data['amounts'])
pd.concat([a,b],axis=1)

在這裏插入圖片描述



4、轉換數據

4.1、啞變量處理類別數據

4.1.1、啞變量處理

  • 數據分析模型中有相當一部分的算法模型都要求輸入的特徵爲數值型,但實際數據中特徵的類型不一定只有數值型,還會存在相當一部分的類別型,這部分的特徵需要經過啞變量處理纔可以放入模型之中。
  • 啞變量處理的原理示例如圖:
    在這裏插入圖片描述

4.1.2、get_dummies函數

  • Python中可以利用pandas庫中的get_dummies函數對類別型特徵進行啞變量處理。、
  • pandas.get_dummies(data, prefix=None, prefix_sep=’_’, dummy_na=False, columns=None, sparse=False, drop_first=False)
參數名稱 說明
data 接收array、DataFrame或者Series。表示需要啞變量處理的數據。無默認
prefix 接收string、string的列表或者string的dict。表示啞變量化後列名的前綴。默認爲None
prefix_sep 接收string。表示前綴的連接符。默認爲‘_’
dummy_na 接收boolean。表示是否爲Nan值添加一列。默認爲False
columns 接收類似list的數據。表示DataFrame中需要編碼的列名。默認爲None,表示對所有object和category類型進行編碼
sparse 接收boolean。表示虛擬列是否是稀疏的。默認爲False
drop_first 接收boolean。表示是否通過從k個分類級別中刪除第一級來獲得k-1個分類級別。默認爲False
pd.get_dummies(data['dishes_name'])

在這裏插入圖片描述

4.1.3、啞變量處理的特點

  • 對於一個類別型特徵,若其取值有m個,則經過啞變量處理後就變成了m個二元特徵,並且這些特徵互斥,每次只有一個激活,這使得數據變得稀疏。
  • 對類別型特徵進行啞變量處理主要解決了部分算法模型無法處理類別型數據的問題,這在一定程度上起到了擴充特徵的作用。由於數據變成了稀疏矩陣的形式,因此也加速了算法模型的運算速度。

4.2、離散化連續型數據

4.2.1、離散化

  • 某些模型算法,特別是某些分類算法如ID3決策樹算法和Apriori算法等,要求數據是離散的,此時就需要將連續型特徵(數值型)變換成離散型特徵(類別型)。
  • 連續特徵的離散化就是在數據的取值範圍內設定若干個離散的劃分點,將取值範圍劃分爲一些離散化的區間,最後用不同的符號或整數值代表落在每個子區間中的數據值。
  • 因此離散化涉及兩個子任務,即確定分類數以及如何將連續型數據映射到這些類別型數據上。其原理如圖:
    在這裏插入圖片描述

4.2.2、等寬法

  • 將數據的值域分成具有相同寬度的區間,區間的個數由數據本身的特點決定或者用戶指定,與製作頻率分佈表類似。pandas提供了cut函數,可以進行連續型數據的等寬離散化,其基礎語法格式如下:
  • pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
參數名稱 說明
x 接收數組或Series。代表需要進行離散化處理的數據。無默認
bins 接收int,list,array,tuple。若爲int,代表離散化後的類別數目;若爲序列類型的數據,則表示進行切分的區間,每兩個數間隔爲一個區間。無默認
right 接收boolean。代表右側是否爲閉區間。默認爲True
labels 接收list,array。代表離散化後各個類別的名稱。默認爲空
retbins 接收boolean。代表是否返回區間標籤。默認爲False
precision 接收int。顯示的標籤的精度。默認爲3
  • 使用等寬法離散化的缺陷爲:等寬法離散化對數據分佈具有較高要求,若數據分佈不均勻,那麼各個類的數目也會變得非常不均勻,有些區間包含許多數據,而另外一些區間的數據極少,這會嚴重損壞所建立的模型。
pd.cut(data['amounts'],bins=5)
0         (36.4, 71.8]
1         (36.4, 71.8]
2        (0.823, 36.4]
3        (0.823, 36.4]
4        (0.823, 36.4]
             ...      
10032    (0.823, 36.4]
10033    (0.823, 36.4]
10034     (36.4, 71.8]
10035    (0.823, 36.4]
10036    (0.823, 36.4]
Name: amounts, Length: 10037, dtype: category
Categories (5, interval[float64]): [(0.823, 36.4] < (36.4, 71.8] < (71.8, 107.2] < (107.2, 142.6] < (142.6, 178.0]]

統計頻數:

pd.cut(data['amounts'],bins=5).value_counts()
(0.823, 36.4]     5461
(36.4, 71.8]      3157
(71.8, 107.2]      839
(142.6, 178.0]     426
(107.2, 142.6]     154
Name: amounts, dtype: int64

4.2.3、等頻法

  • cut函數雖然不能夠直接實現等頻離散化,但是可以通過定義將相同數量的記錄放進每個區間。
  • 等頻法離散化的方法相比較於等寬法離散化而言,避免了類分佈不均勻的問題,但同時卻也有可能將數值非常接近的兩個值分到不同的區間以滿足每個區間中固定的數據個數。
def samefreq(data, k):
    w = data.quantile(np.arange(0,1 + 1/k, 1/k))
    return pd.cut(data, w)
samefreq(data['amounts'], k=5).value_counts()
(18.0, 32.0]     2107
(39.0, 58.0]     2080
(32.0, 39.0]     1910
(1.0, 18.0]      1891
(58.0, 178.0]    1863
Name: amounts, dtype: int64

4.2.4、基於聚類分析的方法

  • 一維聚類的方法包括兩個步驟:
    • 將連續型數據用聚類算法(如K-Means算法等)進行聚類。
    • 處理聚類得到的簇,將合併到一個簇的連續型數據做同一標記。
  • 聚類分析的離散化方法需要用戶指定簇的個數,用來決定產生的區間數。
  • k-Means聚類分析的離散化方法可以很好地根據現有特徵的數據分佈狀況進行聚類,但是由於k-Means算法本身的缺陷,用該方法進行離散化時依舊需要指定離散化後類別的數目。此時需要配合聚類算法評價方法,找出最優的聚類簇數目。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章