數(shù)據(jù)缺失、混亂、重復(fù)怎么辦?最全數(shù)據(jù)清洗指南讓你所向披靡
要獲得優(yōu)秀的模型,首先需要清洗數(shù)據(jù)。這是一篇如何在 Python 中執(zhí)行數(shù)據(jù)清洗的分步指南。
在擬合機(jī)器學(xué)習(xí)或統(tǒng)計(jì)模型之前,我們通常需要清洗數(shù)據(jù)。用雜亂數(shù)據(jù)訓(xùn)練出的模型無(wú)法輸出有意義的結(jié)果。
數(shù)據(jù)清洗:從記錄集、表或數(shù)據(jù)庫(kù)中檢測(cè)和修正(或刪除)受損或不準(zhǔn)確記錄的過(guò)程。它識(shí)別出數(shù)據(jù)中不完善、不準(zhǔn)確或不相關(guān)的部分,并替換、修改或刪除這些臟亂的數(shù)據(jù)。
「數(shù)據(jù)清洗」光定義就這么長(zhǎng),執(zhí)行過(guò)程肯定既枯燥又耗時(shí)。
圖源:https://www.kdnuggets.com/2017/09/cartoon-machine-learning-class.html
為了將數(shù)據(jù)清洗簡(jiǎn)單化,本文介紹了一種新型完備分步指南,支持在 Python 中執(zhí)行數(shù)據(jù)清洗流程。讀者可以學(xué)習(xí)找出并清洗以下數(shù)據(jù)的方法:
- 缺失數(shù)據(jù);
- 不規(guī)則數(shù)據(jù)(異常值);
- 不必要數(shù)據(jù):重復(fù)數(shù)據(jù)(repetitive data)、復(fù)制數(shù)據(jù)(duplicate data)等;
- 不一致數(shù)據(jù):大寫(xiě)、地址等;
該指南使用的數(shù)據(jù)集是 Kaggle 競(jìng)賽 Sberbank 俄羅斯房地產(chǎn)價(jià)值預(yù)測(cè)競(jìng)賽數(shù)據(jù)(該項(xiàng)目的目標(biāo)是預(yù)測(cè)俄羅斯的房?jī)r(jià)波動(dòng))。本文并未使用全部數(shù)據(jù),僅選取了其中的一部分樣本。
本文兩位作者 Lianne & Justin。
在進(jìn)入數(shù)據(jù)清洗流程之前,我們先來(lái)看一下數(shù)據(jù)概況。
- # import packages
- import pandas as pd
- import numpy as np
- import seaborn as sns
- import matplotlib.pyplot as plt
- import matplotlib.mlab as mlab
- import matplotlib
- plt.style.use('ggplot')
- from matplotlib.pyplot import figure
- %matplotlib inline
- matplotlib.rcParams['figure.figsize'] = (12,8)
- pd.options.mode.chained_assignment = None
- # read the data
- df = pd.read_csv('sberbank.csv')
- # shape and data types of the data
- print(df.shape)
- print(df.dtypes)
- # select numeric columns
- df_numeric = df.select_dtypes(include=[np.number])
- numeric_cols = df_numeric.columns.values
- print(numeric_cols)
- # select non numeric columns
- df_non_numeric = df.select_dtypes(exclude=[np.number])
- non_numeric_cols = df_non_numeric.columns.values
- print(non_numeric_cols)
從以上結(jié)果中,我們可以看到該數(shù)據(jù)集共有 30,471 行、292 列,還可以辨別特征屬于數(shù)值變量還是分類變量。這些都是有用的信息。
現(xiàn)在,我們可以瀏覽「臟」數(shù)據(jù)類型檢查清單,并一一攻破。
開(kāi)始吧!
缺失數(shù)據(jù)
處理缺失數(shù)據(jù)/缺失值是數(shù)據(jù)清洗中最棘手也最常見(jiàn)的部分。很多模型可以與其他數(shù)據(jù)問(wèn)題和平共處,但大多數(shù)模型無(wú)法接受缺失數(shù)據(jù)問(wèn)題。
如何找出缺失數(shù)據(jù)?
本文將介紹三種方法,幫助大家更多地了解數(shù)據(jù)集中的缺失數(shù)據(jù)。
方法 1:缺失數(shù)據(jù)熱圖
當(dāng)特征數(shù)量較少時(shí),我們可以通過(guò)熱圖對(duì)缺失數(shù)據(jù)進(jìn)行可視化。
- cols = df.columns[:30] # first 30 columns
- colours = ['#000099', '#ffff00'] # specify the colours - yellow is missing. blue is not missing.
- sns.heatmap(df[cols].isnull(), cmap=sns.color_palette(colours))
下表展示了前 30 個(gè)特征的缺失數(shù)據(jù)模式。橫軸表示特征名,縱軸表示觀察值/行數(shù),黃色表示缺失數(shù)據(jù),藍(lán)色表示非缺失數(shù)據(jù)。
例如,下圖中特征 life_sq 在多個(gè)行中存在缺失值。而特征 floor 只在第 7000 行左右出現(xiàn)零星缺失值。
缺失數(shù)據(jù)熱圖
方法 2:缺失數(shù)據(jù)百分比列表
當(dāng)數(shù)據(jù)集中存在很多特征時(shí),我們可以為每個(gè)特征列出缺失數(shù)據(jù)的百分比。
- # if it's a larger dataset and the visualization takes too long can do this.
- # % of missing.
- for col in df.columns:
- pct_missing = np.mean(df[col].isnull())
- print('{} - {}%'.format(col, round(pct_missing*100)))
得到如下列表,該表展示了每個(gè)特征的缺失值百分比。
具體而言,我們可以從下表中看到特征 life_sq 有 21% 的缺失數(shù)據(jù),而特征 floor 僅有 1% 的缺失數(shù)據(jù)。該列表有效地總結(jié)了每個(gè)特征的缺失數(shù)據(jù)百分比情況,是對(duì)熱圖可視化的補(bǔ)充。
前 30 個(gè)特征的缺失數(shù)據(jù)百分比列表
方法 3:缺失數(shù)據(jù)直方圖
在存在很多特征時(shí),缺失數(shù)據(jù)直方圖也不失為一種有效方法。
要想更深入地了解觀察值中的缺失值模式,我們可以用直方圖的形式進(jìn)行可視化。
- # first create missing indicator for features with missing data
- for col in df.columns:
- missing = df[col].isnull()
- num_missing = np.sum(missing)
- if num_missing > 0:
- print('created missing indicator for: {}'.format(col))
- df['{}_ismissing'.format(col)] = missing
- # then based on the indicator, plot the histogram of missing values
- ismissing_cols = [col for col in df.columns if 'ismissing' in col]
- df['num_missing'] = df[ismissing_cols].sum(axis=1)
- df['num_missing'].value_counts().reset_index().sort_values(by='index').plot.bar(x='index', y='num_missing')
直方圖可以幫助在 30,471 個(gè)觀察值中識(shí)別缺失值狀況。
例如,從下圖中可以看到,超過(guò) 6000 個(gè)觀察值不存在缺失值,接近 4000 個(gè)觀察值具備一個(gè)缺失值。
缺失數(shù)據(jù)直方圖
如何處理缺失數(shù)據(jù)?
這方面沒(méi)有統(tǒng)一的解決方案。我們必須研究特定特征和數(shù)據(jù)集,據(jù)此決定處理缺失數(shù)據(jù)的最佳方式。
下面介紹了四種最常用的缺失數(shù)據(jù)處理方法。不過(guò),如果情況較為復(fù)雜,我們需要?jiǎng)?chuàng)造性地使用更復(fù)雜的方法,如缺失數(shù)據(jù)建模。
解決方案 1:丟棄觀察值
在統(tǒng)計(jì)學(xué)中,該方法叫做成列刪除(listwise deletion),需要丟棄包含缺失值的整列觀察值。
只有在我們確定缺失數(shù)據(jù)無(wú)法提供信息時(shí),才可以執(zhí)行該操作。否則,我們應(yīng)當(dāng)考慮其他解決方案。
此外,還存在其他標(biāo)準(zhǔn)。
例如,從缺失數(shù)據(jù)直方圖中,我們可以看到只有少量觀察值的缺失值數(shù)量超過(guò) 35。因此,我們可以創(chuàng)建一個(gè)新的數(shù)據(jù)集 df_less_missing_rows,該數(shù)據(jù)集刪除了缺失值數(shù)量超過(guò) 35 的觀察值。
- # drop rows with a lot of missing values.
- ind_missing = df[df['num_missing'] > 35].index
- df_less_missing_rows = df.drop(ind_missing, axis=0)
解決方案 2:丟棄特征
與解決方案 1 類似,我們只在確定某個(gè)特征無(wú)法提供有用信息時(shí)才丟棄它。
例如,從缺失數(shù)據(jù)百分比列表中,我們可以看到 hospital_beds_raion 具備較高的缺失值百分比——47%,因此我們丟棄這一整個(gè)特征。
- # hospital_beds_raion has a lot of missing.
- # If we want to drop.
- cols_to_drop = ['hospital_beds_raion']
- df_less_hos_beds_raion = df.drop(cols_to_drop, axis=1)
解決方案 3:填充缺失數(shù)據(jù)
當(dāng)特征是數(shù)值變量時(shí),執(zhí)行缺失數(shù)據(jù)填充。對(duì)同一特征的其他非缺失數(shù)據(jù)取平均值或中位數(shù),用這個(gè)值來(lái)替換缺失值。
當(dāng)特征是分類變量時(shí),用眾數(shù)(最頻值)來(lái)填充缺失值。
以特征 life_sq 為例,我們可以用特征中位數(shù)來(lái)替換缺失值。
- # replace missing values with the median.
- med = df['life_sq'].median()
- print(med)
- df['life_sq'] = df['life_sq'].fillna(med)
此外,我們還可以對(duì)所有數(shù)值特征一次性應(yīng)用同樣的填充策略。
- # impute the missing values and create the missing value indicator variables for each numeric column.
- df_numeric = df.select_dtypes(include=[np.number])
- numeric_cols = df_numeric.columns.values
- for col in numeric_cols:
- missing = df[col].isnull()
- num_missing = np.sum(missing)
- if num_missing > 0: # only do the imputation for the columns that have missing values.
- print('imputing missing values for: {}'.format(col))
- df['{}_ismissing'.format(col)] = missing
- med = df[col].median()
- df[col] = df[col].fillna(med)
很幸運(yùn),本文使用的數(shù)據(jù)集中的分類特征沒(méi)有缺失值。不然,我們也可以對(duì)所有分類特征一次性應(yīng)用眾數(shù)填充策略。
- # impute the missing values and create the missing value indicator variables for each non-numeric column.
- df_non_numeric = df.select_dtypes(exclude=[np.number])
- non_numeric_cols = df_non_numeric.columns.values
- for col in non_numeric_cols:
- missing = df[col].isnull()
- num_missing = np.sum(missing)
- if num_missing > 0: # only do the imputation for the columns that have missing values.
- print('imputing missing values for: {}'.format(col))
- df['{}_ismissing'.format(col)] = missing
- top = df[col].describe()['top'] # impute with the most frequent value.
- df[col] = df[col].fillna(top)
解決方案 4:替換缺失值
對(duì)于分類特征,我們可以添加新的帶值類別,如 _MISSING_。對(duì)于數(shù)值特征,我們可以用特定值(如-999)來(lái)替換缺失值。
這樣,我們就可以保留缺失值,使之提供有價(jià)值的信息。
- # categorical
- df['sub_area'] = df['sub_area'].fillna('_MISSING_')
- # numeric
- df['life_sq'] = df['life_sq'].fillna(-999)
不規(guī)則數(shù)據(jù)(異常值)
異常值指與其他觀察值具備顯著差異的數(shù)據(jù),它們可能是真的異常值也可能是錯(cuò)誤。
如何找出異常值?
根據(jù)特征的屬性(數(shù)值或分類),使用不同的方法來(lái)研究其分布,進(jìn)而檢測(cè)異常值。
方法 1:直方圖/箱形圖
當(dāng)特征是數(shù)值變量時(shí),使用直方圖和箱形圖來(lái)檢測(cè)異常值。
下圖展示了特征 life_sq 的直方圖。
- # histogram of life_sq.
- df['life_sq'].hist(bins=100)
由于數(shù)據(jù)中可能存在異常值,因此下圖中數(shù)據(jù)高度偏斜。
直方圖
為了進(jìn)一步研究特征,我們來(lái)看一下箱形圖。
- # box plot.
- df.boxplot(column=['life_sq'])
從下圖中我們可以看到,異常值是一個(gè)大于 7000 的數(shù)值。
箱形圖
方法 2:描述統(tǒng)計(jì)學(xué)
對(duì)于數(shù)值特征,當(dāng)異常值過(guò)于獨(dú)特時(shí),箱形圖無(wú)法顯示該值。因此,我們可以查看其描述統(tǒng)計(jì)學(xué)。
例如,對(duì)于特征 life_sq,我們可以看到其最大值是 7478,而上四分位數(shù)(數(shù)據(jù)的第 75 個(gè)百分位數(shù)據(jù))是 43。因此值 7478 是異常值。
- df['life_sq'].describe()
方法 3:條形圖
當(dāng)特征是分類變量時(shí),我們可以使用條形圖來(lái)了解其類別和分布。
例如,特征 ecology 具備合理的分布。但如果某個(gè)類別「other」僅有一個(gè)值,則它就是異常值。
- # bar chart - distribution of a categorical variable
- df['ecology'].value_counts().plot.bar()
條形圖
其他方法:還有很多方法可以找出異常值,如散點(diǎn)圖、z 分?jǐn)?shù)和聚類,本文不過(guò)多探討全部方法。
如何處理異常值?
盡管異常值不難檢測(cè),但我們必須選擇合適的處理辦法。而這高度依賴于數(shù)據(jù)集和項(xiàng)目目標(biāo)。
處理異常值的方法與處理缺失值有些類似:要么丟棄,要么修改,要么保留。(讀者可以返回上一章節(jié)處理缺失值的部分查看相關(guān)解決方案。)
不必要數(shù)據(jù)
處理完缺失數(shù)據(jù)和異常值,現(xiàn)在我們來(lái)看不必要數(shù)據(jù),處理不必要數(shù)據(jù)的方法更加直接。
輸入到模型中的所有數(shù)據(jù)應(yīng)服務(wù)于項(xiàng)目目標(biāo)。不必要數(shù)據(jù)即無(wú)法增加價(jià)值的數(shù)據(jù)。
這里將介紹三種主要的不必要數(shù)據(jù)類型。
不必要數(shù)據(jù)類型 1:信息不足/重復(fù)
有時(shí)一個(gè)特征不提供信息,是因?yàn)樗鼡碛刑嗑邆湎嗤档男小?/p>
如何找出重復(fù)數(shù)據(jù)?
我們可以為具備高比例相同值的特征創(chuàng)建一個(gè)列表。
例如,下圖展示了 95% 的行是相同值的特征。
- num_rows = len(df.index)
- low_information_cols = [] #
- for col in df.columns:
- cnts = df[col].value_counts(dropna=False)
- top_pct = (cnts/num_rows).iloc[0]
- if top_pct > 0.95:
- low_information_cols.append(col)
- print('{0}: {1:.5f}%'.format(col, top_pct*100))
- print(cnts)
- print()
我們可以逐一查看這些變量,確認(rèn)它們是否提供有用信息。(此處不再詳述。)
如何處理重復(fù)數(shù)據(jù)?
我們需要了解重復(fù)特征背后的原因。當(dāng)它們的確無(wú)法提供有用信息時(shí),我們就可以丟棄它。
不必要數(shù)據(jù)類型 2:不相關(guān)
再次強(qiáng)調(diào),數(shù)據(jù)需要為項(xiàng)目提供有價(jià)值的信息。如果特征與項(xiàng)目試圖解決的問(wèn)題無(wú)關(guān),則這些特征是不相關(guān)數(shù)據(jù)。
如何找出不相關(guān)數(shù)據(jù)?
瀏覽特征,找出不相關(guān)的數(shù)據(jù)。
例如,記錄多倫多氣溫的特征無(wú)法為俄羅斯房?jī)r(jià)預(yù)測(cè)項(xiàng)目提供任何有用信息。
如何處理不相關(guān)數(shù)據(jù)?
當(dāng)這些特征無(wú)法服務(wù)于項(xiàng)目目標(biāo)時(shí),刪除之。
不必要數(shù)據(jù)類型 3:復(fù)制
復(fù)制數(shù)據(jù)即,觀察值存在副本。
復(fù)制數(shù)據(jù)有兩個(gè)主要類型。
復(fù)制數(shù)據(jù)類型 1:基于所有特征
如何找出基于所有特征的復(fù)制數(shù)據(jù)?
這種復(fù)制發(fā)生在觀察值內(nèi)所有特征的值均相同的情況下,很容易找出。
我們需要先刪除數(shù)據(jù)集中的唯一標(biāo)識(shí)符 id,然后刪除復(fù)制數(shù)據(jù)得到數(shù)據(jù)集 df_dedupped。對(duì)比 df 和 df_dedupped 這兩個(gè)數(shù)據(jù)集的形態(tài),找出復(fù)制行的數(shù)量。
- # we know that column 'id' is unique, but what if we drop it?
- df_dedupped = df.drop('id', axis=1).drop_duplicates()
- # there were duplicate rows
- print(df.shape)
- print(df_dedupped.shape)
我們發(fā)現(xiàn),有 10 行是完全復(fù)制的觀察值。
如何處理基于所有特征的復(fù)制數(shù)據(jù)?
刪除這些復(fù)制數(shù)據(jù)。
復(fù)制數(shù)據(jù)類型 2:基于關(guān)鍵特征
如何找出基于關(guān)鍵特征的復(fù)制數(shù)據(jù)?
有時(shí)候,最好的方法是刪除基于一組唯一標(biāo)識(shí)符的復(fù)制數(shù)據(jù)。
例如,相同使用面積、相同價(jià)格、相同建造年限的兩次房產(chǎn)交易同時(shí)發(fā)生的概率接近零。
我們可以設(shè)置一組關(guān)鍵特征作為唯一標(biāo)識(shí)符,比如 timestamp、full_sq、life_sq、floor、build_year、num_room、price_doc。然后基于這些特征檢查是否存在復(fù)制數(shù)據(jù)。
- key = ['timestamp', 'full_sq', 'life_sq', 'floor', 'build_year', 'num_room', 'price_doc']
- df.fillna(-999).groupby(key)['id'].count().sort_values(ascending=False).head(20)
基于這組關(guān)鍵特征,我們找到了 16 條復(fù)制數(shù)據(jù)。
如何處理基于關(guān)鍵特征的復(fù)制數(shù)據(jù)?
刪除這些復(fù)制數(shù)據(jù)。
- # drop duplicates based on an subset of variables.
- key = ['timestamp', 'full_sq', 'life_sq', 'floor', 'build_year', 'num_room', 'price_doc']
- df_dedupped2 = df.drop_duplicates(subset=key)
- print(df.shape)
- print(df_dedupped2.shape)
刪除 16 條復(fù)制數(shù)據(jù),得到新數(shù)據(jù)集 df_dedupped2。
不一致數(shù)據(jù)
在擬合模型時(shí),數(shù)據(jù)集遵循特定標(biāo)準(zhǔn)也是很重要的一點(diǎn)。我們需要使用不同方式來(lái)探索數(shù)據(jù),找出不一致數(shù)據(jù)。大部分情況下,這取決于觀察和經(jīng)驗(yàn)。不存在運(yùn)行和修復(fù)不一致數(shù)據(jù)的既定代碼。
下文介紹了四種不一致數(shù)據(jù)類型。
不一致數(shù)據(jù)類型 1:大寫(xiě)
在類別值中混用大小寫(xiě)是一種常見(jiàn)的錯(cuò)誤。這可能帶來(lái)一些問(wèn)題,因?yàn)?Python 分析對(duì)大小寫(xiě)很敏感。
如何找出大小寫(xiě)不一致的數(shù)據(jù)?
我們來(lái)看特征 sub_area。
- df['sub_area'].value_counts(dropna=False)
它存儲(chǔ)了不同地區(qū)的名稱,看起來(lái)非常標(biāo)準(zhǔn)化。
但是,有時(shí)候相同特征內(nèi)存在不一致的大小寫(xiě)使用情況?!窹oselenie Sosenskoe」和「pOseleNie sosenskeo」指的是相同的地區(qū)。
如何處理大小寫(xiě)不一致的數(shù)據(jù)?
為了避免這個(gè)問(wèn)題,我們可以將所有字母設(shè)置為小寫(xiě)(或大寫(xiě))。
- # make everything lower case.
- df['sub_area_lower'] = df['sub_area'].str.lower()
- df['sub_area_lower'].value_counts(dropna=False)
不一致數(shù)據(jù)類型 2:格式
我們需要執(zhí)行的另一個(gè)標(biāo)準(zhǔn)化是數(shù)據(jù)格式。比如將特征從字符串格式轉(zhuǎn)換為 DateTime 格式。
如何找出格式不一致的數(shù)據(jù)?
特征 timestamp 在表示日期時(shí)是字符串格式。
- df
如何處理格式不一致的數(shù)據(jù)?
使用以下代碼進(jìn)行格式轉(zhuǎn)換,并提取日期或時(shí)間值。然后,我們就可以很容易地用年或月的方式分析交易量數(shù)據(jù)。
- df['timestamp_dt'] = pd.to_datetime(df['timestamp'], format='%Y-%m-%d')
- df['year'] = df['timestamp_dt'].dt.year
- df['month'] = df['timestamp_dt'].dt.month
- df['weekday'] = df['timestamp_dt'].dt.weekday
- print(df['year'].value_counts(dropna=False))
- print()
- print(df['month'].value_counts(dropna=False))
相關(guān)文章:https://towardsdatascience.com/how-to-manipulate-date-and-time-in-python-like-a-boss-ddea677c6a4d
不一致數(shù)據(jù)類型 3:類別值
分類特征的值數(shù)量有限。有時(shí)由于拼寫(xiě)錯(cuò)誤等原因可能出現(xiàn)其他值。
如何找出類別值不一致的數(shù)據(jù)?
我們需要觀察特征來(lái)找出類別值不一致的情況。舉例來(lái)說(shuō):
由于本文使用的房地產(chǎn)數(shù)據(jù)集不存在這類問(wèn)題,因此我們創(chuàng)建了一個(gè)新的數(shù)據(jù)集。例如,city 的值被錯(cuò)誤輸入為「torontoo」和「tronto」,其實(shí)二者均表示「toronto」(正確值)。
識(shí)別它們的一種簡(jiǎn)單方式是模糊邏輯(或編輯距離)。該方法可以衡量使一個(gè)值匹配另一個(gè)值需要更改的字母數(shù)量(距離)。
已知這些類別應(yīng)僅有四個(gè)值:「toronto」、「vancouver」、「montreal」和「calgary」。計(jì)算所有值與單詞「toronto」(和「vancouver」)之間的距離,我們可以看到疑似拼寫(xiě)錯(cuò)誤的值與正確值之間的距離較小,因?yàn)樗鼈冎挥袔讉€(gè)字母不同。
- from nltk.metrics import edit_distance
- df_city_ex = pd.DataFrame(data={'city': ['torontoo', 'toronto', 'tronto', 'vancouver', 'vancover', 'vancouvr', 'montreal', 'calgary']})
- df_city_ex['city_distance_toronto'] = df_city_ex['city'].map(lambda x: edit_distance(x, 'toronto'))
- df_city_ex['city_distance_vancouver'] = df_city_ex['city'].map(lambda x: edit_distance(x, 'vancouver'))
- df_city_ex
如何處理類別值不一致的數(shù)據(jù)?
我們可以設(shè)置標(biāo)準(zhǔn)將這些拼寫(xiě)錯(cuò)誤轉(zhuǎn)換為正確值。例如,下列代碼規(guī)定所有值與「toronto」的距離在 2 個(gè)字母以內(nèi)。
- msk = df_city_ex['city_distance_toronto'] <= 2
- df_city_ex.loc[msk, 'city'] = 'toronto'
- msk = df_city_ex['city_distance_vancouver'] <= 2
- df_city_ex.loc[msk, 'city'] = 'vancouver'
- df_city_ex
不一致數(shù)據(jù)類型 4:地址
地址特征對(duì)很多人來(lái)說(shuō)是老大難問(wèn)題。因?yàn)槿藗兺鶖?shù)據(jù)庫(kù)中輸入數(shù)據(jù)時(shí)通常不會(huì)遵循標(biāo)準(zhǔn)格式。
如何找出地址不一致的數(shù)據(jù)?
用瀏覽的方式可以找出混亂的地址數(shù)據(jù)。即便有時(shí)我們看不出什么問(wèn)題,也可以運(yùn)行代碼執(zhí)行標(biāo)準(zhǔn)化。
出于隱私原因,本文采用的房地產(chǎn)數(shù)據(jù)集沒(méi)有地址列。因此我們創(chuàng)建具備地址特征的新數(shù)據(jù)集 df_add_ex。
- # no address column in the housing dataset. So create one to show the code.
- df_add_ex = pd.DataFrame(['123 MAIN St Apartment 15', '123 Main Street Apt 12 ', '543 FirSt Av', ' 876 FIRst Ave.'], columns=['address'])
- df_add_ex
我們可以看到,地址特征非?;靵y。
如何處理地址不一致的數(shù)據(jù)?
運(yùn)行以下代碼將所有字母轉(zhuǎn)為小寫(xiě),刪除空格,刪除句號(hào),并將措辭標(biāo)準(zhǔn)化。
- df_add_ex['address_std'] = df_add_ex['address'].str.lower()
- df_add_ex['address_std'] = df_add_ex['address_std'].str.strip() # remove leading and trailing whitespace.
- df_add_ex['address_std'] = df_add_ex['address_std'].str.replace('\\.', '') # remove period.
- df_add_ex['address_std'] = df_add_ex['address_std'].str.replace('\\bstreet\\b', 'st') # replace street with st.
- df_add_ex['address_std'] = df_add_ex['address_std'].str.replace('\\bapartment\\b', 'apt') # replace apartment with apt.
- df_add_ex['address_std'] = df_add_ex['address_std'].str.replace('\\bav\\b', 'ave') # replace apartment with apt.
- df_add_ex
現(xiàn)在看起來(lái)好多了:
結(jié)束了!我們走過(guò)了長(zhǎng)長(zhǎng)的數(shù)據(jù)清洗旅程。
現(xiàn)在你可以運(yùn)用本文介紹的方法清洗所有阻礙你擬合模型的「臟」數(shù)據(jù)了。
【本文是51CTO專欄機(jī)構(gòu)“機(jī)器之心”的原創(chuàng)譯文,微信公眾號(hào)“機(jī)器之心( id: almosthuman2014)”】