干凈整潔的數(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()
② 箱型圖
df.boxplot(column='close', by='ts_code', rot=0)
plt.show()
③ 散點圖
df.plot(kind='scatter', x='close', y='pre_close', rot=0)
plt.show()
二获雕、清洗數(shù)據(jù)
了解數(shù)據(jù)集之后,我們就可以開始對數(shù)據(jù)集進行清洗了收捣,前面提到通常要處理的問題有包含無效信息典鸡,列名不規(guī)范、格式不一致坏晦,存在重復值,缺失值嫁乘,異常值等昆婿,下面我們一個一個來看。
01
去除不需要的行蜓斧、列
在分析一個數(shù)據(jù)集的時候仓蛆,很多信息其實是用不到的,因此挎春,需要去除不必要的行或列看疙。這里以csv文件為例,在導入的時候就可以通過設置pd.read_csv()里面的參數(shù)來實現(xiàn)這個目的直奋。
先來感受一下官方文檔中給出的詳細解釋能庆,里面的參數(shù)是相當?shù)亩啵疚闹唤榻B比較常用的幾個脚线,感興趣的話搁胆,可以好好研究一下文檔,這些參數(shù)還是非常好用的邮绿,能省去很多導入后整理的工作渠旁。
【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ù)
數(shù)據(jù)樣本如下:
導入數(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)常會用到的靶草,希望大家能牢記于心蹄胰。