干货:4个小技巧助你搞定缺失、混乱的数据(附实例代码)
導(dǎo)讀:數(shù)據(jù)工作者經(jīng)常會遇到各種狀況,比如你收集到的數(shù)據(jù)并不像你期待的那樣完整、干凈。此前我們講解了用OpenRefine搞定數(shù)據(jù)清洗,本文進(jìn)一步探討用pandas和NumPy插補(bǔ)缺失數(shù)據(jù)并將數(shù)據(jù)規(guī)范化、標(biāo)準(zhǔn)化。
?
作者:托馬茲·卓巴斯(Tomasz Drabas)
如需轉(zhuǎn)載請聯(lián)系大數(shù)據(jù)(ID:hzdashuju)
?
本文將使用一個(gè)數(shù)據(jù)集,包含985項(xiàng)真實(shí)的房產(chǎn)交易。這些交易是連續(xù)5天內(nèi)在Sacramento發(fā)生的。數(shù)據(jù)下載自:
?
http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv
?
數(shù)據(jù)已轉(zhuǎn)成多種格式,放在GitHub代碼庫的Data/Chapter01文件夾中。
?
https://github.com/drabastomek/practicalDataAnalysisCookbook.git
?
?
01 插補(bǔ)缺失值
?
數(shù)據(jù)的收集工作很棘手。收集工具壞了,調(diào)查問卷上某些問題人們不想回答,或者文件被損壞了;這些還只是數(shù)據(jù)集可能不全的一小部分原因。如果想使用這個(gè)數(shù)據(jù)集,我們有兩個(gè)選擇:忽略缺失的數(shù)據(jù),或者用一些值替代。
?
1. 準(zhǔn)備
?
要實(shí)踐本技巧,你要先裝好pandas模塊。
?
2. 怎么做
?
csv_read DataFrame可供使用。要插補(bǔ)缺失值,你只需要使用下面的代碼(data_imput.py文件):
?
#?估算平均數(shù)以替代空值
csv_read['price_mean']?=?csv_read['price']?\
.fillna(
csv_read.groupby('zip')['price'].transform('mean')
)
?
3. 原理
?
pandas的.fillna(...)方法幫我們處理了所有重活。這是DataFrame對象的一個(gè)方法,將要估算的值作為唯一必須傳入的參數(shù)。
?
查閱pandas文檔中.fillna(...)的部分,了解可傳入的其他參數(shù)。文檔位于:
?
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html
?
在我們的處理過程中,我們假設(shè)每個(gè)郵編可能會有不同的均價(jià)。這就是我們用.groupby(...)方法對數(shù)據(jù)分組的原因。房產(chǎn)的價(jià)格重度依賴于房間的數(shù)目,這個(gè)推論也是成立的;如果我們的數(shù)據(jù)集更大,我們還能考慮beds這個(gè)變量。
?
.groupby(...)方法返回一個(gè)GroupBy對象。其.transform(...)方法高效地對郵編分組,在我們的例子中,分組的依據(jù)是各郵編價(jià)格數(shù)據(jù)的平均數(shù)。
?
現(xiàn)在,.fillna(...)方法簡單地用這個(gè)平均數(shù)替代缺失的觀測數(shù)據(jù)即可。
?
4. 更多
?
插補(bǔ)數(shù)據(jù)不是填補(bǔ)缺失值的唯一方法。數(shù)據(jù)對稱分布且沒有異常值時(shí),才會返回一個(gè)合理的值;如果分布比較偏,平均值是有偏差的。衡量集中趨勢更好的維度是中位數(shù)。我們前面的例子只需要改一個(gè)小地方:
?
#?估算中位數(shù)以替代空值
csv_read['price_median']?=?csv_read['price']?\
.fillna(
csv_read.groupby('zip')['price'].transform('median')
)
?
?
02 將特征規(guī)范化、標(biāo)準(zhǔn)化
?
為了提高計(jì)算效率,我們將特征規(guī)范化(或標(biāo)準(zhǔn)化),這樣不會超出計(jì)算機(jī)的限制。探索模型中變量之間的相互作用時(shí)也建議這么處理。
?
計(jì)算機(jī)是有限制的:整型值是有上限的(盡管目前在64位機(jī)器上這不是個(gè)問題),浮點(diǎn)型的精確度也有上限。
?
數(shù)據(jù)規(guī)范化是讓所有的值落在0到1的范圍內(nèi)(閉區(qū)間)。數(shù)據(jù)標(biāo)準(zhǔn)化是移動其分布,使得數(shù)據(jù)的平均數(shù)是0、標(biāo)準(zhǔn)差是1。
?
1. 準(zhǔn)備
?
要實(shí)踐本技巧,你要先裝好pandas模塊。
?
其他沒有什么要準(zhǔn)備的了。
?
2. 怎么做
?
要實(shí)現(xiàn)規(guī)范化與標(biāo)準(zhǔn)化,我們定義了兩個(gè)輔助函數(shù)(data_standardize.py文件):
?
def?normalize(col):
'''
規(guī)范化
'''
return?(col?-?col.min())?/?(col.max()?-?col.min())
def?standardize(col):
'''
標(biāo)準(zhǔn)化
'''
return?(col?-?col.mean())?/?col.std()
?
3. 原理
?
要規(guī)范化數(shù)據(jù),即讓每個(gè)值都落在0和1之間,我們減去數(shù)據(jù)的最小值,并除以樣本的范圍。統(tǒng)計(jì)學(xué)上的范圍指的是最大值與最小值的差。normalize(...)方法就是做的前面描述的工作:對數(shù)據(jù)的集合,減去最小值,除以范圍。
?
標(biāo)準(zhǔn)化的過程類似:減去平均數(shù),除以樣本的標(biāo)準(zhǔn)差。這樣,處理后的數(shù)據(jù),平均數(shù)為0而標(biāo)準(zhǔn)差為1。standardize(...)方法做了這些處理:
?
csv_read['n_price_mean']?=?normalize(csv_read['price_mean'])
csv_read['s_price_mean']?=?standardize(csv_read['price_mean'])
?
?
03 分級數(shù)據(jù)
?
當(dāng)我們想查看數(shù)據(jù)分布的形狀,或?qū)?shù)據(jù)轉(zhuǎn)換為有序的形式時(shí),數(shù)據(jù)分級就派上用場了。
?
1. 準(zhǔn)備
?
要實(shí)踐本技巧,你要先裝好pandas和NumPy模塊。
?
2. 怎么做
?
可以用下面的代碼(data_binning.py文件)對數(shù)據(jù)分級(比如處理成直方圖):
?
#?根據(jù)線性劃分的價(jià)格的范圍,創(chuàng)建價(jià)格的容器
bins?=?np.linspace(
csv_read['price_mean'].min(),
csv_read['price_mean'].max(),
6
)
#?將容器應(yīng)用到數(shù)據(jù)上
csv_read['b_price']?=?np.digitize(
csv_read['price_mean'],
bins
)
?
3. 原理
?
第一步是創(chuàng)建容器。對于價(jià)格數(shù)據(jù)(缺失值用估算的平均數(shù)填補(bǔ)),我們創(chuàng)建了六個(gè)容器,在最小值和最大值之間均勻分配。.linspace(...)方法做了這點(diǎn)工作:創(chuàng)建長度為6的NumPy數(shù)組,其中每個(gè)元素比前一個(gè)大固定的差值。比如,.linspace(0, 6, 6)生成數(shù)組[0., 1.2, 2.4, 3.6, 4.8, 6.]。
?
NumPy對線性代數(shù)來說是個(gè)強(qiáng)大的數(shù)字處理庫。可輕松處理大型數(shù)組和矩陣,還提供了極其豐富的函數(shù)操作數(shù)據(jù)。想了解更多,可訪問:
?
http://www.numpy.org
?
.digitize(...)方法對指定列中的每個(gè)值,都返回所屬的容器索引。第一個(gè)參數(shù)是要分級的列,第二個(gè)參數(shù)是容器的數(shù)組。
?
使用DataFrame的.value_counts()得到每個(gè)容器中的記錄計(jì)數(shù),counts_b = csv_read['b_price'].value_counts()。
?
4. 更多
?
有時(shí)候我們不會用均勻間隔的值,我們會讓每個(gè)桶中擁有相同的數(shù)目。要達(dá)成這個(gè)目標(biāo),我們可以使用分位數(shù)。
?
分位數(shù)與百分位數(shù)有緊密的聯(lián)系。區(qū)別在于百分位數(shù)返回的是給定百分?jǐn)?shù)的值,而分位數(shù)返回的是給定分位點(diǎn)的值。想了解更多,可訪問:
?
https://www.stat.auckland.ac.nz/~ihaka/787/lectures-quantiles-handouts.pdf
?
我們想把列拆成十分位數(shù),即10個(gè)(差不多)相等的容器。要做到這點(diǎn),我們可以使用下面的代碼(你可以一眼看出其和之前方法的相似之處):
?
#?根據(jù)十分位數(shù)創(chuàng)建容器
decile?=?csv_read['price_mean'].quantile(np.linspace(0,?1,?11))
#?將容器應(yīng)用到數(shù)據(jù)上
csv_read['p_price']?=?np.digitize(
csv_read['price_mean'],
decile
)
?
.quantile(...)方法可以傳一個(gè)(0到1之間的)數(shù)字,來表明要返回的分位數(shù)(例如,0.5是中位數(shù),0.25和0.75是上下四分位數(shù))。它也可以傳入一個(gè)分位的列表,返回相應(yīng)的值的數(shù)組。.linspace(0, 1, 11)方法會生成這個(gè)數(shù)組:
?
[?0.,?0.1,?0.2,?0.3,?0.4,?0.5,?0.6,?0.7,?0.8,?0.9,?1.]
?
所以,.quantile(...)方法會以price_mean列的最小值開始,直到最大值,返回十分位數(shù)的列表。
?
?
04 編碼分類變量
?
為數(shù)據(jù)的探索階段準(zhǔn)備的最后一步就是分類變量了。有些軟件包在背后做了這個(gè)工作,但最好還是理解這步處理的時(shí)機(jī)與做法。
?
統(tǒng)計(jì)模型只能接受有序的數(shù)據(jù)。分類變量(有時(shí)根據(jù)上下文可表示為數(shù)字)不能直接在模型中使用。要使用它們,我們要先進(jìn)行編碼,也就是給它們一個(gè)唯一的數(shù)字編號。這解釋了什么時(shí)候做。至于如何做—應(yīng)用下述技巧即可。
?
1. 準(zhǔn)備
?
要實(shí)踐本技巧,你要先裝好pandas模塊。
?
其他沒有什么要準(zhǔn)備的了。
?
2. 怎么做
?
pandas又提供了一個(gè)方法,幫我們做完所有事(data_dummy_code.py文件):
?
#?根據(jù)房產(chǎn)類型處理的簡單代碼
csv_read?=?pd.get_dummies(
csv_read,
prefix='d',
columns=['type']
)
?
3. 原理
?
.get_dummies(...)方法將分類變量轉(zhuǎn)換為簡單的變量。比如,考慮一個(gè)變量,以三種水平中的某一種作為值:
?
1?One
2?Two
3?Three
?
需要用三列進(jìn)行編碼:
?
1?One?1?0?0
2?Two?0?1?0
3?Three?0?0?1
?
有時(shí)可用兩列。如果有一個(gè)水平等效于null的話,我們可以這樣做:
?
1?One?1?0?
2?Two?0?1?
3?Three?0?0?
?
.get_dummies(...)方法的第一個(gè)參數(shù)是DataFrame對象。columns參數(shù)指定了代碼要處理的DataFrame的列(或某些列,因?yàn)榭梢詡魅肓斜?#xff09;。通過指定前綴,我們告訴方法生成的列名以d打頭;本例中生成的列會叫d_Condo。下劃線是默認(rèn)的,可以通過指定prefix_sep參數(shù)更改。
?
.get_dummies(...)方法的完整參數(shù)列表,參見:
?
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html
?
關(guān)于作者:托馬茲·卓巴斯(Tomasz Drabas),微軟數(shù)據(jù)科學(xué)家,致力于解決高維特征空間的問題。他有超過13年的數(shù)據(jù)分析和數(shù)據(jù)科學(xué)經(jīng)驗(yàn):在歐洲、澳大利亞和北美洲三大洲期間,工作領(lǐng)域遍及高新技術(shù)、航空、電信、金融和咨詢。
本文摘編自《數(shù)據(jù)分析實(shí)戰(zhàn)》,經(jīng)出版方授權(quán)發(fā)布。
?
延伸閱讀《數(shù)據(jù)分析實(shí)戰(zhàn)》
點(diǎn)擊上圖了解及購買
轉(zhuǎn)載請聯(lián)系微信:togo-maruko
?
推薦語:通過大量的現(xiàn)實(shí)案例,詳細(xì)講解數(shù)據(jù)分析相關(guān)的各種方法。
?
?
據(jù)統(tǒng)計(jì),99%的大咖都完成了這個(gè)神操作
▼
?
?
更多精彩
?
在公眾號后臺對話框輸入以下關(guān)鍵詞
查看更多優(yōu)質(zhì)內(nèi)容!
?
PPT?|?報(bào)告?|?讀書?|?書單
大數(shù)據(jù)?|?揭秘?|?人工智能?|?AI
Python?|?機(jī)器學(xué)習(xí)?|?深度學(xué)習(xí)?|?神經(jīng)網(wǎng)絡(luò)
可視化?|?區(qū)塊鏈?|?干貨?|?數(shù)學(xué)
?
猜你想看
?
-
NumPy入門攻略:手把手帶你玩轉(zhuǎn)這款強(qiáng)大的數(shù)據(jù)分析和計(jì)算工具
-
谷歌最新開源前端框架了解一下?前端小白都能看懂的8本書
-
入門科普:一文看懂機(jī)器學(xué)習(xí)3種類型的概念、根本差別及應(yīng)用
-
只需4步,微軟數(shù)據(jù)科學(xué)家教你用OpenRefine搞定數(shù)據(jù)清洗
?
?
Q:?你都遇到過哪些不完整的數(shù)據(jù)?
歡迎留言與大家分享
覺得不錯,請把這篇文章分享給你的朋友
轉(zhuǎn)載 / 投稿請聯(lián)系:baiyu@hzbook.com
更多精彩,請?jiān)诤笈_點(diǎn)擊“歷史文章”查看
點(diǎn)擊閱讀原文,了解更多
總結(jié)
以上是生活随笔為你收集整理的干货:4个小技巧助你搞定缺失、混乱的数据(附实例代码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 73页PPT,教你从0到1构建用户画像系
- 下一篇: 婚姻大数据:姐弟恋最靠谱,男同学们,小姐