Python數(shù)據(jù)清洗80%的工作量,看這篇就夠了

image.png

干凈整潔的數(shù)據(jù)是后續(xù)進行研究和分析的基礎(chǔ)炎滞。數(shù)據(jù)科學家們會花費大量的時間來清理數(shù)據(jù)集兽埃,毫不夸張地說蒜魄,數(shù)據(jù)清洗會占據(jù)他們80%的工作時間,而真正用來分析數(shù)據(jù)的時間只占到20%左右挂签。

所以,數(shù)據(jù)清洗到底是在清洗些什么盼产?

通常來說饵婆,你所獲取到的原始數(shù)據(jù)不能直接用來分析,因為它們會有各種各樣的問題戏售,如包含無效信息侨核,列名不規(guī)范、格式不一致蜈项,存在重復值芹关,缺失值,異常值等.....

本文會給大家介紹如何用Python中自帶的Pandas和NumPy庫進行數(shù)據(jù)清洗紧卒。在正式講解之前侥衬,先簡單介紹一下這兩個非常好用的庫。

Pandas的名稱來自于Panel data和Python數(shù)據(jù)分析data analysis,是Python的一個數(shù)據(jù)分析包轴总,最初由AQR Capital Management于2008年4月開發(fā)直颅,被作為金融數(shù)據(jù)分析工具,為時間序列分析提供了很好的支持怀樟,并于2009年底開源出來功偿。

NumPy是Numeric Python的縮寫,是Python的一種開源的數(shù)值計算擴展往堡,可用來存儲和處理大型矩陣matrix械荷,比Python自身的嵌套列表結(jié)構(gòu)要高效的多,提供了許多高級的數(shù)值編程工具虑灰,如:矩陣數(shù)據(jù)類型吨瞎、矢量處理,以及精密的運算庫穆咐,專為進行嚴格的數(shù)字處理而產(chǎn)生颤诀。

目錄
一、了解數(shù)據(jù)

二对湃、清洗數(shù)據(jù)

去除不需要的行崖叫、列

重新命名列

重新設置索引

用字符串操作規(guī)范列

用函數(shù)規(guī)范列

刪除重復數(shù)據(jù)

填充缺失值

三、總結(jié)

【注】為了清晰直觀地展示數(shù)據(jù)清洗操作拍柒,本文會用到幾個不同的數(shù)據(jù)集心傀,重點是方法的講解。

【工具】Python 3

一斤儿、了解數(shù)據(jù)

拿到一個全新的數(shù)據(jù)集剧包,應該從哪里入手?

沒錯往果,我們需要先了解數(shù)據(jù)疆液,看看它長什么樣子。這里用tushare.pro上面的日線行情數(shù)據(jù)進行展示陕贮,以浦發(fā)銀行(600000.SH)為例堕油。常用的方法和屬性如下:

.head()

.tail()

.shape

.columns

.info()

.describe()

.value_counts()

首先,獲取數(shù)據(jù):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tushare as ts


pd.set_option('display.max_columns', 100)  # 設置顯示數(shù)據(jù)的最大列數(shù)肮之,防止出現(xiàn)省略號…掉缺,導致數(shù)據(jù)顯示不全
pd.set_option('expand_frame_repr', False)  # 當列太多時不自動換行


pro = ts.pro_api()
df = pro.daily(ts_code='600000.SH', start_date='20190401', end_date='20190430')

.head() 查看前n行數(shù)據(jù),默認值是5

df.head()
Out[1]: 
     ts_code trade_date   open   high    low  close  pre_close  change  pct_chg         vol       amount
0  600000.SH   20190430  11.70  12.09  11.70  11.97      11.48    0.49   4.2683  1234747.38  1466714.710
1  600000.SH   20190429  11.35  11.54  11.34  11.48      11.32    0.16   1.4134   385869.38   442046.727
2  600000.SH   20190426  11.43  11.56  11.28  11.32      11.54   -0.22  -1.9064   424695.81   485267.261
3  600000.SH   20190425  11.56  11.69  11.48  11.54      11.62   -0.08  -0.6885   408761.29   473973.527
4  600000.SH   20190424  11.76  11.77  11.51  11.62      11.70   -0.08  -0.6838   382011.08   444929.313

.tail() 查看后n行數(shù)據(jù)戈擒,默認值是5

df.tail()
Out[2]: 
      ts_code trade_date   open   high    low  close  pre_close  change  pct_chg        vol      amount
16  600000.SH   20190408  11.79  11.96  11.65  11.72      11.71    0.01   0.0854  778703.73  920513.531
17  600000.SH   20190404  11.55  11.71  11.54  11.71      11.50    0.21   1.8261  752325.27  876099.547
18  600000.SH   20190403  11.37  11.54  11.34  11.50      11.44    0.06   0.5245  502710.29  575799.446
19  600000.SH   20190402  11.50  11.52  11.41  11.44      11.44    0.00   0.0000  467147.10  534896.810
20  600000.SH   20190401  11.36  11.52  11.29  11.44      11.28    0.16   1.4184  706374.05  808657.530

.shape 查看數(shù)據(jù)維數(shù)

df.shape
Out[3]: (21, 11)

.columns 查看所有列名

df.columns
Out[4]: 
Index(['ts_code', 'trade_date', 'open', 'high', 'low', 'close', 'pre_close',
       'change', 'pct_chg', 'vol', 'amount'],
      dtype='object')

.info() 查看索引眶明、數(shù)據(jù)類型和內(nèi)存信息

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 21 entries, 0 to 20
Data columns (total 11 columns):
ts_code       21 non-null object
trade_date    21 non-null object
open          21 non-null float64
high          21 non-null float64
low           21 non-null float64
close         21 non-null float64
pre_close     21 non-null float64
change        21 non-null float64
pct_chg       21 non-null float64
vol           21 non-null float64
amount        21 non-null float64
dtypes: float64(9), object(2)
memory usage: 1.9+ KB

.describe() 查看每列數(shù)據(jù)的基本統(tǒng)計值,包括計數(shù)值筐高、均值搜囱、標準差丑瞧、最小最大值、1/4蜀肘、1/2绊汹、3/4分位數(shù)。

df.describe()
Out[7]: 
            open       high        low      close  pre_close     change    pct_chg           vol        amount
count  21.000000  21.000000  21.000000  21.000000  21.000000  21.000000  21.000000  2.100000e+01  2.100000e+01
mean   11.630476  11.777619  11.524286  11.637143  11.604286   0.032857   0.296252  5.734931e+05  6.704836e+05
std     0.215348   0.228930   0.184840   0.207512   0.206799   0.193213   1.671099  2.333355e+05  2.792896e+05
min    11.350000  11.520000  11.280000  11.320000  11.280000  -0.300000  -2.497900  2.627369e+05  3.017520e+05
25%    11.470000  11.560000  11.410000  11.480000  11.470000  -0.060000  -0.519900  4.102754e+05  4.739735e+05
50%    11.560000  11.750000  11.480000  11.540000  11.540000   0.000000   0.000000  5.027103e+05  5.757994e+05
75%    11.760000  11.990000  11.650000  11.720000  11.710000   0.100000   0.839600  7.050917e+05  8.161270e+05
max    12.020000  12.200000  11.880000  12.010000  12.010000   0.490000   4.268300  1.234747e+06  1.466715e+06

.value_counts() 查看Series對象的唯一值和計數(shù)值

df['close'].value_counts(dropna=False)
Out[8]: 
11.48    2
11.47    2
11.71    2
11.54    2
11.91    2
11.44    2
11.72    1
11.95    1
11.70    1
11.32    1
11.49    1
12.01    1
11.62    1
11.50    1
11.97    1
Name: close, dtype: int64

如果上面這些操作還不夠直觀的話扮宠,就作圖看看西乖,需要先導入Python可視化庫matplotlib, 為了規(guī)范代碼書寫,統(tǒng)一寫在了最前面坛增。

① 直方圖

df['close'].plot(kind='hist', rot=0)
plt.show()
image.png

② 箱型圖

df.boxplot(column='close', by='ts_code', rot=0)
plt.show()
image.png

③ 散點圖

df.plot(kind='scatter', x='close', y='pre_close', rot=0)
plt.show()
image.png

二获雕、清洗數(shù)據(jù)
了解數(shù)據(jù)集之后,我們就可以開始對數(shù)據(jù)集進行清洗了收捣,前面提到通常要處理的問題有包含無效信息典鸡,列名不規(guī)范、格式不一致坏晦,存在重復值,缺失值嫁乘,異常值等昆婿,下面我們一個一個來看。

01
去除不需要的行蜓斧、列
在分析一個數(shù)據(jù)集的時候仓蛆,很多信息其實是用不到的,因此挎春,需要去除不必要的行或列看疙。這里以csv文件為例,在導入的時候就可以通過設置pd.read_csv()里面的參數(shù)來實現(xiàn)這個目的直奋。

先來感受一下官方文檔中給出的詳細解釋能庆,里面的參數(shù)是相當?shù)亩啵疚闹唤榻B比較常用的幾個脚线,感興趣的話搁胆,可以好好研究一下文檔,這些參數(shù)還是非常好用的邮绿,能省去很多導入后整理的工作渠旁。


image.png

【header】默認header=0,即將文件中的0行作為列名和數(shù)據(jù)的開頭船逮,但有時候0行的數(shù)據(jù)是無關(guān)的顾腊,我們想跳過0行,讓1行作為數(shù)據(jù)的開頭挖胃,可以通過將header設置為1來實現(xiàn)杂靶。

【usecols】根據(jù)列的位置或名字梆惯,如[0,1,2]或[‘a(chǎn)’, ‘b’, ‘c’],選出特定的列伪煤。

【nrows】要導入的數(shù)據(jù)行數(shù)加袋,在數(shù)據(jù)量很大、但只想導入其中一部分時使用抱既。

獲取數(shù)據(jù):

從NYC OpenData網(wǎng)站下載csv格式原始數(shù)據(jù)


image.png

數(shù)據(jù)樣本如下:


image.png

導入數(shù)據(jù)职烧,只選取前100行和特定幾列。
subset_columns = ['Job #', 'Doc #', 'Borough', 'Initial Cost', 'Total Est. Fee']
df = pd.read_csv('文件路徑', nrows=100, usecols=subset_columns)
df.head()
Out[15]: 
       Job #  Doc #   Borough Initial Cost Total Est. Fee
0  420291794      1    QUEENS     $2000.00        $100.00
1  420291801      1    QUEENS    $15000.00        $151.50
2  340644128      1  BROOKLYN    $44726.00        $234.00
3  421685439      1    QUEENS        $0.00        $243.00
4  421677974      2    QUEENS   $105000.00       $1275.60

再看一下將header設置為1的效果防泵,但這里其實不需要這么做蚀之,因為0行數(shù)據(jù)是有用的。

df = pd.read_csv('文件路徑', nrows=100, header=1)
df.head()
Out[15]: 
0  420291794      1    QUEENS     $2000.00        $100.00
1  420291801      1    QUEENS    $15000.00        $151.50
2  340644128      1  BROOKLYN    $44726.00        $234.00
3  421685439      1    QUEENS        $0.00        $243.00
4  421677974      2    QUEENS   $105000.00       $1275.60

如果在數(shù)據(jù)導入之后捷泞,還想刪除某些行和列足删,可以用 .drop() 方法。

先創(chuàng)建一個列表list锁右,把不需要的列名放進去失受,再調(diào)用.drop() 方法,參數(shù)axis為1時代表列咏瑟,為0時代表行拂到,參數(shù)inplace=True表示不創(chuàng)建新的對象,直接對原始對象進行修改码泞。這里我們刪除前兩列兄旬。

to_drop = ['Job #', 'Doc #']
df.drop(to_drop, axis=1, inplace=True)
df.head()
Out[22]: 
    Borough Initial Cost Total Est. Fee
0    QUEENS     $2000.00        $100.00
1    QUEENS    $15000.00        $151.50
2  BROOKLYN    $44726.00        $234.00
3    QUEENS        $0.00        $243.00
4    QUEENS   $105000.00       $1275.60

02
重新命名列
當原始數(shù)據(jù)的列名不好理解,或者不夠簡潔時余寥,可以用.rename()方法進行修改领铐。這里我們把英文的列名改成中文,先創(chuàng)建一個字典宋舷,把要修改的列名定義好绪撵,然后調(diào)用rename()方法。

new_names = {'Borough': '區(qū)', 'Initial Cost': '初始成本', 'Total Est. Fee': '總附加費用'}
df.rename(columns=new_names, inplace=True)
df.head()
Out[23]: 
          區(qū)        初始成本     總附加費用
0    QUEENS    $2000.00   $100.00
1    QUEENS   $15000.00   $151.50
2  BROOKLYN   $44726.00   $234.00
3    QUEENS       $0.00   $243.00
4    QUEENS  $105000.00  $1275.60

03

重新設置索引

數(shù)據(jù)默認的索引是從0開始的有序整數(shù)肥缔,但如果想把某一列設置為新的索引莲兢,可以用.set_index()方法實現(xiàn),在示例中我們把"區(qū)"這列設置為新索引续膳。

df.set_index('區(qū)', inplace=True)
df.head()
Out[24]: 
                初始成本     總附加費用
區(qū)                             
QUEENS      $2000.00   $100.00
QUEENS     $15000.00   $151.50
BROOKLYN   $44726.00   $234.00
QUEENS         $0.00   $243.00
QUEENS    $105000.00  $1275.60

04

用字符串操作規(guī)范列
字符串str操作是非常實用的改艇,因為列中總是會包含不必要的字符,常用的方法如下:

lower()

upper()

capitalize()

replace()

strip()

split()

get()

contains()

find()

str.lower() 是把大寫轉(zhuǎn)換成小寫坟岔,同理谒兄,str.upper()是把小寫轉(zhuǎn)換成大寫,將示例中用大寫字母表示的索引轉(zhuǎn)換成小寫社付,效果如下:

df.index = df.index.str.lower()
df.head()
Out[25]: 
                初始成本     總附加費用
區(qū)                             
queens      $2000.00   $100.00
queens     $15000.00   $151.50
brooklyn   $44726.00   $234.00
queens         $0.00   $243.00
queens    $105000.00  $1275.60

str.capitalize() 設置首字母大寫

df.index = df.index.str.capitalize()
df.head()
Out[26]: 
                初始成本     總附加費用
區(qū)                             
Queens      $2000.00   $100.00
Queens     $15000.00   $151.50
Brooklyn   $44726.00   $234.00
Queens         $0.00   $243.00
Queens    $105000.00  $1275.60

str.replace('', '') 替換特定字符承疲。這里把列中的美元符號去掉邻耕,替換成空字符。

df['初始成本'] = df['初始成本'].str.replace('$', '')
df['總附加費用'] = df['總附加費用'].str.replace('$', '')
df.head()
Out[27]: 
               初始成本    總附加費用
區(qū)                           
Queens      2000.00   100.00
Queens     15000.00   151.50
Brooklyn   44726.00   234.00
Queens         0.00   243.00
Queens    105000.00  1275.60

str.strip() 去除字符串中的頭尾空格燕鸽、以及\n \t

df['初始成本'] = '   ' + df['初始成本']
df['初始成本'][0]
Out[28]: '   2000.00'

df['初始成本'] = df['初始成本'].str.strip()
df['初始成本'][0]
Out[29]: '2000.00'

str.split('x') 使用字符串中的'x'字符作為分隔符兄世,將字符串分隔成列表。這里將列中的值以'.'進行分割啊研,效果如下:

df['總附加費用'] = df['總附加費用'].str.split('.')
df.head()
Out[30]: 
               初始成本       總附加費用
區(qū)                              
Queens      2000.00   [100, 00]
Queens     15000.00   [151, 50]
Brooklyn   44726.00   [234, 00]
Queens         0.00   [243, 00]
Queens    105000.00  [1275, 60]

str.get() 選取列表中某個位置的值御滩。接著上面分割后的結(jié)果,我們用str.get(0)取出列表中前一個位置的數(shù)值党远,生成新的一列“總附加費用_整數(shù)”削解,即取出金額中的整數(shù)部分。

df['總附加費用_整數(shù)'] = df['總附加費用'].str.get(0)
df.head()
Out[31]: 
               初始成本       總附加費用 總附加費用_整數(shù)
區(qū)                                       
Queens      2000.00   [100, 00]      100
Queens     15000.00   [151, 50]      151
Brooklyn   44726.00   [234, 00]      234
Queens         0.00   [243, 00]      243
Queens    105000.00  [1275, 60]     1275

str.contains() 判斷是否存在某個字符沟娱,返回的是布爾值氛驮。這里判斷一下"總附加費用_整數(shù)"列中是否包含字符'0'。

df['總附加費用_整數(shù)'].str.contains('0')
Out[33]: 
區(qū)
Queens            True
Queens           False
Brooklyn         False
Queens           False
Queens           False

str.find()檢測字符串中是否包含子字符串str济似,如果是矫废,則返回該子字符串開始位置的索引值。示例中的'0'字符最開始出現(xiàn)的位置是1砰蠢。

df['總附加費用_整數(shù)'][0]
Out[13]: '100'
df['總附加費用_整數(shù)'][0].find('0')
Out[14]: 1

學完基本的字符串操作方法磷脯,我們來看一下如何結(jié)合NumPy來提高字符串操作的效率。

獲取數(shù)據(jù)娩脾,這里我們用一個新的數(shù)據(jù)集,下載鏈接如下打毛,里面包含兩個csv文件和一個txt文件:

https://github.com/realpython/python-data-cleaning

① BL-Flickr-Images-Book.csv

② olympics.csv

③ university_towns.txt

導入csv文件①柿赊,先觀察一下"Place of Publication"這一列。

df = pd.read_csv('文件路徑')
df['Place of Publication'].head(10)
Out[38]: 
0                                 London
1               London; Virtue & Yorston
2                                 London
3                                 London
4                                 London
5                                 London
6                                 London
7    pp. 40. G. Bryan & Co: Oxford, 1898
8                                London]
9                                 London
Name: Place of Publication, dtype: object

我們發(fā)現(xiàn)幻枉,這一列中的格式并不統(tǒng)一碰声,比如1行中的London; Virtue & Yorston,London后面的部分我們不需要熬甫,還有7行的pp. 40. G. Bryan & Co: Oxford, 1898胰挑,有效信息只是Oxford睦裳。

再用.tail(10)方法觀察這一列的最后十行:

df['Place of Publication'].tail(10)
Out[39]: 
8277               New York
8278                 London
8279               New York
8280                 London
8281    Newcastle-upon-Tyne
8282                 London
8283                  Derby
8284                 London
8285    Newcastle upon Tyne
8286                 London
Name: Place of Publication, dtype: object

我們發(fā)現(xiàn)嘶炭,8281行的Newcastle-upon-Tyne中間有連字符,但8285行卻沒有比藻,這些都是要解決的格式不規(guī)范的問題郑象。

為了清洗這一列贡这,我們可以將Pandas中的.str()方法與NumPy的np.where函數(shù)相結(jié)合,np.where函數(shù)是Excel的IF()宏的矢量化形式厂榛,它的語法如下:

>>> np.where(condition, then, else)

如果condition條件為真盖矫,則執(zhí)行then丽惭,否則執(zhí)行else。這里的condition條件可以是一個類數(shù)組的對象辈双,也可以是一個布爾表達式责掏,我們也可以利用np.where函數(shù)嵌套多個條件進行矢量化計算和判斷。

>>> np.where(condition1, x1, 
        np.where(condition2, x2, 
            np.where(condition3, x3, ...)))

下面的這個實例湃望,就是同時嵌套兩個條件解決上面提到的那兩個字符串問題换衬。思路是,如果字符串里面包含'London'喜爷,就用'London'代替冗疮,這樣可以去除其他冗余信息,否則檩帐,如果字符串里面包含'Oxford'术幔,則用'Oxford'代替,同時如果字符串里面包含符號'-'湃密,則用空格代替诅挑。

pub = df['Place of Publication']
london = pub.str.contains('London')
oxford = pub.str.contains('Oxford')


df['Place of Publication'] = np.where(london, 'London',
                                      np.where(oxford, 'Oxford',
                                               pub.str.replace('-', ' ')))

打印出前十行和后十行,結(jié)果如下泛源,可以和整理前的數(shù)據(jù)進行對比拔妥。

df['Place of Publication'].head(10)
Out[42]: 
0    London
1    London
2    London
3    London
4    London
5    London
6    London
7    Oxford
8    London
9    London
Name: Place of Publication, dtype: object
df['Place of Publication'].tail(10)
Out[43]: 
8277               New York
8278                 London
8279               New York
8280                 London
8281    Newcastle upon Tyne
8282                 London
8283                  Derby
8284                 London
8285    Newcastle upon Tyne
8286                 London
Name: Place of Publication, dtype: object

05

用函數(shù)規(guī)范列

在某些情況下,數(shù)據(jù)不規(guī)范的情況并不局限于某一列达箍,而是更廣泛地分布在整個表格中没龙。因此,自定義函數(shù)并應用于整個表格中的每個元素會更加高效缎玫。用applymap()方法可以實現(xiàn)這個功能硬纤,它類似于內(nèi)置的map()函數(shù),只不過它是將函數(shù)應用于整個表格中的所有元素赃磨。

我們打開文件txt文件③筝家,先觀察一下數(shù)據(jù):

$ head Datasets/univerisity_towns.txt

Alabama[edit]
Auburn (Auburn University)[1]
Florence (University of North Alabama)
Jacksonville (Jacksonville State University)[2]
Livingston (University of West Alabama)[2]
Montevallo (University of Montevallo)[2]
Troy (Troy University)[2]
Tuscaloosa (University of Alabama, Stillman College, Shelton State)[3][4]
Tuskegee (Tuskegee University)[5]
Alaska[edit]

觀察發(fā)現(xiàn),數(shù)據(jù)格式有如下特點:
州A[edit]
城市A(大學)
城市B(大學)
州B[edit]
城市A(大學)
城市B(大學)
......

我們可以利用這一數(shù)據(jù)格式邻辉,創(chuàng)建一個(州溪王、市)元組列表,并將該列表轉(zhuǎn)化成一個DataFrame值骇。先創(chuàng)建一個列表莹菱,列表中包含州和城市(大學)信息。

university_towns = []
with open('D:/code/tushare interpret and tech team/python-data-cleaning-master/Datasets/university_towns.txt') as file:
    for line in file:
        if '[edit]' in line:  # 該行有[edit]
            state = line      # 將改行信息賦值給“州”吱瘩,記住這個“州”芒珠,直到找到下一個為止
        else:
            university_towns.append((state, line))  # 否則,改行為城市信息搅裙,并且它們都屬于上面的“州”


university_towns[:5]
Out[44]: 
[('Alabama[edit]\n', 'Auburn (Auburn University)[1]\n'),
 ('Alabama[edit]\n', 'Florence (University of North Alabama)\n'),
 ('Alabama[edit]\n', 'Jacksonville (Jacksonville State University)[2]\n'),
 ('Alabama[edit]\n', 'Livingston (University of West Alabama)[2]\n'),
 ('Alabama[edit]\n', 'Montevallo (University of Montevallo)[2]\n')]

用pd.DataFrame()方法將這個列表轉(zhuǎn)換成一個DataFrame皱卓,并將列設置為"State"和"RegionName"裹芝。Pandas將接受列表中的每個元素,并將元組左邊的值傳入"State"列娜汁,右邊的值傳入"RegionName"列嫂易。

towns_df = pd.DataFrame(university_towns, columns=['State', 'RegionName'])
towns_df.head()
Out[45]: 
             State                                         RegionName
0  Alabama[edit]\n                    Auburn (Auburn University)[1]\n
1  Alabama[edit]\n           Florence (University of North Alabama)\n
2  Alabama[edit]\n  Jacksonville (Jacksonville State University)[2]\n
3  Alabama[edit]\n       Livingston (University of West Alabama)[2]\n
4  Alabama[edit]\n         Montevallo (University of Montevallo)[2]\n

接下來就要對列中的字符串進行整理,"State"列中的有效信息是州名掐禁,"RegionName"列中的有效信息是城市名怜械,其他的字符都可以刪掉。當然傅事,除了用之前提到的利用循環(huán)和.str()方法相結(jié)合的方式進行操作缕允,我們還可以選擇用applymap()方法,它會將傳入的函數(shù)作用于整個DataFrame所有行列中的每個元素蹭越。

先定義函數(shù)get_citystate(item)障本,功能是只提取元素中的有效信息。

def get_citystate(item):
    if ' (' in item:
        return item[:item.find(' (')]
    elif '[' in item:
        return item[:item.find('[')]
    else:
        return item

然后响鹃,我們將這個函數(shù)傳入applymap()驾霜,并應用于towns_df,結(jié)果如下:

towns_df = towns_df.applymap(get_citystate)
towns_df.head()
Out[48]: 
     State    RegionName
0  Alabama        Auburn
1  Alabama      Florence
2  Alabama  Jacksonville
3  Alabama    Livingston
4  Alabama    Montevallo

現(xiàn)在towns_df表格看起來是不是干凈多了买置!

06

刪除重復數(shù)據(jù)

重復數(shù)據(jù)會消耗不必要的內(nèi)存粪糙,在處理數(shù)據(jù)時執(zhí)行不必要的計算,還會使分析結(jié)果出現(xiàn)偏差忿项。因此蓉冈,我們有必要學習如何刪除重復數(shù)據(jù)。

先看一個來自DataCamp的數(shù)據(jù)集轩触,調(diào)用info()方法打印出每列數(shù)據(jù)的具體信息和內(nèi)存信息洒擦,共有24092行數(shù)據(jù),內(nèi)存占用量是753.0+ KB怕膛。

tracks = billboard[['year', 'artist', 'track', 'time']]
print(tracks.info())

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 24092 entries, 0 to 24091
Data columns (total 4 columns):
year      24092 non-null int64
artist    24092 non-null object
track     24092 non-null object
time      24092 non-null object
dtypes: int64(1), object(3)
memory usage: 753.0+ KB
None

下面調(diào)用.drop_duplicates()函數(shù)刪除重復數(shù)據(jù)。

In [11]: tracks_no_duplicates = tracks.drop_duplicates()
... print(tracks_no_duplicates.info())
... 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 317 entries, 0 to 316
Data columns (total 4 columns):
year      317 non-null int64
artist    317 non-null object
track     317 non-null object
time      317 non-null object
dtypes: int64(1), object(3)
memory usage: 12.4+ KB
None

刪完之后我們發(fā)現(xiàn)秦踪,數(shù)據(jù)量減少到了317個褐捻,內(nèi)存占用縮減至12.4+ KB。

07

填充缺失值

數(shù)據(jù)集中經(jīng)常會存在缺失值椅邓,學會正確處理它們很重要柠逞,因為在計算的時候,有些無法處理缺失值景馁,有些則在默認情況下跳過缺失值板壮。而且,了解缺失的數(shù)據(jù)合住,并思考用什么值來填充它們绰精,對做出無偏的數(shù)據(jù)分析至關(guān)重要撒璧。

同樣是來自DataCamp的一個存在缺失值的數(shù)據(jù)集:

In [3]: airquality.head(10)
Out[3]: 
   Ozone  Solar.R  Wind  Temp  Month  Day
0   41.0    190.0   7.4    67      5    1
1   36.0    118.0   8.0    72      5    2
2   12.0    149.0  12.6    74      5    3
3   18.0    313.0  11.5    62      5    4
4    NaN      NaN  14.3    56      5    5
5   28.0      NaN  14.9    66      5    6
6   23.0    299.0   8.6    65      5    7
7   19.0     99.0  13.8    59      5    8
8    8.0     19.0  20.1    61      5    9
9    NaN    194.0   8.6    69      5   10

以"Ozone"列為例,我們可以調(diào)用fillna()函數(shù)笨使,用該列的均值.mean()填充NaN值卿樱。

oz_mean = airquality.Ozone.mean()
airquality['Ozone'] = airquality['Ozone'].fillna(oz_mean)
print(airquality.head(10))

       Ozone  Solar.R  Wind  Temp  Month  Day
0  41.000000    190.0   7.4    67      5    1
1  36.000000    118.0   8.0    72      5    2
2  12.000000    149.0  12.6    74      5    3
3  18.000000    313.0  11.5    62      5    4
4  43.195402      NaN  14.3    56      5    5
5  28.000000      NaN  14.9    66      5    6
6  23.000000    299.0   8.6    65      5    7
7  19.000000     99.0  13.8    59      5    8
8   8.000000     19.0  20.1    61      5    9
9  43.195402    194.0   8.6    69      5   10

三、總結(jié)

了解如何進行數(shù)據(jù)清洗非常重要硫椰,因為它是數(shù)據(jù)科學的重要組成部分繁调。好在Python提供了非常好用的Pandas和NumPy庫來幫助我們清理數(shù)據(jù)集,本文介紹的方法都是在實際中經(jīng)常會用到的靶草,希望大家能牢記于心蹄胰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市奕翔,隨后出現(xiàn)的幾起案子裕寨,更是在濱河造成了極大的恐慌,老刑警劉巖糠悯,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帮坚,死亡現(xiàn)場離奇詭異,居然都是意外死亡互艾,警方通過查閱死者的電腦和手機试和,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纫普,“玉大人阅悍,你說我怎么就攤上這事∽蚣冢” “怎么了节视?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長假栓。 經(jīng)常有香客問我寻行,道長,這世上最難降的妖魔是什么匾荆? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任拌蜘,我火速辦了婚禮,結(jié)果婚禮上牙丽,老公的妹妹穿的比我還像新娘简卧。我一直安慰自己,他們只是感情好烤芦,可當我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布举娩。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铜涉。 梳的紋絲不亂的頭發(fā)上智玻,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機與錄音骄噪,去河邊找鬼尚困。 笑死,一個胖子當著我的面吹牛链蕊,可吹牛的內(nèi)容都是我干的事甜。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼滔韵,長吁一口氣:“原來是場噩夢啊……” “哼逻谦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起陪蜻,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤邦马,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宴卖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滋将,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年症昏,在試婚紗的時候發(fā)現(xiàn)自己被綠了随闽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡肝谭,死狀恐怖掘宪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情攘烛,我是刑警寧澤魏滚,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站坟漱,受9級特大地震影響鼠次,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芋齿,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一腥寇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沟突,春花似錦、人聲如沸捕传。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至职辅,卻和暖如春棒呛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背域携。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工簇秒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人秀鞭。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓趋观,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锋边。 傳聞我的和親對象是個殘疾皇子皱坛,可洞房花燭夜當晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容