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

image.png

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

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

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

本文會給大家介紹如何用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ù)

去除不需要的行、列

重新命名列

重新設(shè)置索引

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

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

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

填充缺失值

三、總結(jié)

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

【工具】Python 3

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

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

沒錯,我們需要先了解數(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è)置顯示數(shù)據(jù)的最大列數(shù),防止出現(xiàn)省略號…,導(dǎo)致數(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

如果上面這些操作還不夠直觀的話,就作圖看看,需要先導(dǎo)入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ī)范、格式不一致,存在重復(fù)值,缺失值,異常值等,下面我們一個一個來看。

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

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


image.png

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

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

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

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

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


image.png

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


image.png

導(dǎo)入數(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設(shè)置為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ù)導(dǎo)入之后,還想刪除某些行和列,可以用 .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è)置索引

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

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() 設(shè)置首字母大寫

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

學(xué)完基本的字符串操作方法,我們來看一下如何結(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

導(dǎo)入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ù)并應(yīng)用于整個表格中的每個元素會更加高效。用applymap()方法可以實現(xiàn)這個功能,它類似于內(nèi)置的map()函數(shù),只不過它是將函數(shù)應(yīng)用于整個表格中的所有元素。

我們打開文件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(大學(xué))
城市B(大學(xué))
州B[edit]
城市A(大學(xué))
城市B(大學(xué))
......

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

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,并將列設(shè)置為"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(),并應(yīng)用于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

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

重復(fù)數(shù)據(jù)會消耗不必要的內(nèi)存,在處理數(shù)據(jù)時執(zhí)行不必要的計算,還會使分析結(jié)果出現(xiàn)偏差。因此,我們有必要學(xué)習(xí)如何刪除重復(fù)數(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ù)刪除重復(fù)數(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)常會存在缺失值,學(xué)會正確處理它們很重要,因為在計算的時候,有些無法處理缺失值,有些則在默認情況下跳過缺失值。而且,了解缺失的數(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ù)科學(xué)的重要組成部分。好在Python提供了非常好用的Pandas和NumPy庫來幫助我們清理數(shù)據(jù)集,本文介紹的方法都是在實際中經(jīng)常會用到的,希望大家能牢記于心。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容