寫在最前
Pandas是機(jī)器學(xué)習(xí)工作流程中,對數(shù)據(jù)進(jìn)行預(yù)處理的重要工具罕模。本筆記是同學(xué)在學(xué)習(xí)七月在線機(jī)器學(xué)習(xí)訓(xùn)練營二期中的<pandas花式數(shù)據(jù)統(tǒng)計(jì)與分析技能>時的投稿筆記评腺,分為上下兩篇。本筆記旨在記錄并整理寒老師講授的知識點(diǎn)淑掌,分享以供二期同學(xué)們交流及學(xué)習(xí)蒿讥。
Pandas簡介
1)Pandas是什么?
Pandas是Panel data and data analysis的簡寫抛腕,是一個專門用來數(shù)據(jù)處理和數(shù)據(jù)分析的Python工具庫芋绸。
2)特點(diǎn)
基于numpy庫
底層C實(shí)現(xiàn),效率極高
對矩陣(高維數(shù)組)做計(jì)算
使用起來用在excel/R/SQL担敌,快速入手
3)相關(guān)資源:
pandas官方網(wǎng)站《10 Minutes to pandas》
(http://pandas.pydata.org/pandas-docs/stable/10min.html)
寒老師推薦的pandas速查表摔敛,(學(xué)員)群文件共享下載
csv讀寫
比較簡單,略過柄错,更多選項(xiàng)查看pd.read_csv和pd.to_csv的幫助舷夺,如何分隔符,跳過多少行售貌,頭數(shù)给猾,指定數(shù)據(jù)類型等。
Pandas的兩種數(shù)據(jù)類型:
1)Series
一個series是一個一維的數(shù)據(jù)類型颂跨,其中每一個元素都有一個標(biāo)簽敢伸。series類似于Numpy中元素帶標(biāo)簽的數(shù)組,或者Python中的字典恒削。其中池颈,標(biāo)簽可以是數(shù)字或者字符串。
理解為一個列
#導(dǎo)入相應(yīng)庫
import numpy as np
import pandas as pd
1.1 從列表初始化series[默認(rèn)數(shù)字index]
my_list=[7,'Beijing','19',3.1415,-10000,'Happy']
series1=pd.Series(my_list)
#從列表初始化Series
series1[1] #結(jié)果為'Beijing'
series1[1:4] #Series這種數(shù)據(jù)類型默認(rèn)用0到N這種格式做為索引index
b Beijing
c 19
d 3.1415
dtype: object
什么是Pandas里的index呢钓丰?
可以理解為Python字典中的key,可以通過這個key訪問對應(yīng)的值躯砰。
那Series就可以想象成為一個KV對應(yīng)的結(jié)構(gòu)。
1.2 從列表初始化series携丁,自己指定series的索引
my_list=[7,'Beijing','19',3.1415,-10000,'Happy']
series1=pd.Series(my_list, index=['a','b','c','d','e','f'])
從列表初始化Series琢歇,并自定義index
a 7
b Beijing
c 19
d 3.1415
e -10000
f Happy
dtype: object
#使用自定義index訪問Series
series1['a']
7
series1['f']
'Happy'
即使是自定義索引來初始化Series了,依舊可以通過數(shù)字來訪問。
series1[1:4]
b Beijing
c 19
d 3.1415
dtype: object
s1=pd.Series([1,2,3,4,5,6]
index=pd.date_range('20130101',periods=6))
帶標(biāo)簽李茫,標(biāo)簽是時間序列
s2=pd.Series(list('china! '))
不指定標(biāo)簽揭保,系統(tǒng)自動是從0開始,
1.3 從字典初始化series
因?yàn)樽值溥@種數(shù)據(jù)結(jié)構(gòu)本身就是kv對應(yīng)型的魄宏,因?yàn)榭梢灾苯佑脕順?gòu)建series秸侣。index自動為字典的key
cities={'Beijing':55000,'Shanghai':60000,'Shenzhen':50000,
'Hangzhou':20000,'Guangzhou':45000,'Suzhou':None}
series3=pd.Series(cities)
series3
Beijing 55000.0
Guangzhou 45000.0
Hangzhou 20000.0
Shanghai 60000.0
Shenzhen 50000.0
Suzhou NaN
dtype: float64
1.4 從numpy對象初始化series
series4=pd.Series(np.random.randn(5),index=[list('abcde')])
series4
a -0.362932
b 1.670863
c -0.665555
d 0.402865
e 1.789551
dtype: float64
2)DataFrame
一個DataFrame就是一張表格。Series可以理解為一維數(shù)組宠互,DataFrame是一個二維數(shù)據(jù)味榛,DataFrame是由多個Series組成的(可以理解為Series的集合)
2.1 從已有字典構(gòu)建
population={'city':['Beijing','Shanghai','Guangzhou','Shenzhen',
'Hangzhou','Chongqi'],'year':[2016,2017,2016,2017,2016,2016],
'population':[2100,2300,1000,700,500,500]}
df1=pd.DataFrame(population)
df1
city population year
0 Beijing 2100 2016
1 Shanghai 2300 2017
2 Guangzhou 1000 2016
3 Shenzhen 700 2017
4 Hangzhou 500 2016
5 Chongqi 500 2016
2.2 從list的字典中構(gòu)建
l1=[{'JackMa':100000,'Han':80000,'David':10000},{'JackMa':9999999,'Han':90000}]
df3=pd.DataFrame(l1)
df3
David Han JackMa
0 10000.0 80000 100000
1 NaN 90000 9999999
2.3 從已有Series構(gòu)建
s1=pd.Series(list('china'))
s2=pd.Series(list('powers'))
df2=pd.DataFrame({'s1':s1,'s2':s2})
df2 #兩個Series按index對齊(這里的index為默認(rèn)的**0**至N),
如果對應(yīng)的index沒有名秀,則填為NaN*
s1 s2
0 c p
1 h o
2 i w
3 n e
4 a r
5 NaN s
Index索引
理解index就是對應(yīng) 每個行value的一個key励负。這樣去理解簡單些。
1)默認(rèn)類型
population={'city':['Beijing','Shanghai','Guangzhou','Shenzhen',
'Hangzhou','Chongqi'],'year':[2016,2017,2016,2017,2016,2016],
'population':[2100,2300,1000,700,500,500]
}
df4.index #查看索引
RangeIndex(start=0, stop=6, step=1)
df 默認(rèn)索引均為從0開始匕得,步長為1继榆,總長為總行數(shù)減1的序列。
2)自定義索引并查看類型
pd.Index(list('china'))
Index(['c', 'h', 'i', 'n', 'a'], dtype='object')
type(pd.Index(list('china')))
<class 'pandas.core.indexes.base.Index'>
3)使用自定義索引
df4.index=list('china!')
df4 #可以看到這時的索引已經(jīng)變**成指定的字母了
city population year
c Beijing 2100 2016.0
h Shanghai 2300 NaN
i Guangzhou 1000 2016.0
n Shenzhen 700 2017.0
a Hangzhou 500 2016.0
! Chongqi 500 2016.0
df4.ix[['n','a'],[0,1]] #正常使用并訪問
city population
n Shenzhen 700
a Hangzhou 500
4)多層index
series6=pd.Series(np.random.randn(10),
index=[['a','a','a','b','b','c','c','d','d','d'],[1,2,3,1,2,1,2,1,2,3]])
series6.index
MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
labels=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 0, 1, 0, 1, 2]])
多層index的訪問
series6['b':'c']
b 1 0.198059
2 0.418935
c 1 -0.146183
2 0.134893
dtype: float64
series6[:2]
a 1 0.898547
2 0.132076
dtype: float64
5)unstack
series6
a 1 0.898547
2 0.132076
3 -0.911465
b 1 0.198059
2 0.418935
c 1 -0.146183
2 0.134893
d 1 0.925714
2 0.657029
3 -0.237139
dtype: float64
series6.unstack()
1 2 3
a 0.898547 0.132076 -0.911465
b 0.198059 0.418935 NaN
c -0.146183 0.134893 NaN
d 0.925714 0.657029 -0.237139
type(series6.unstack()) #unstack一個Series后汁掠,變?yōu)镈ataFrame了略吨。
<class 'pandas.core.frame.DataFrame'>
寒老師:千萬不要因?yàn)閜andas功能強(qiáng)大就給自己挖坑,開始的時候就老老實(shí)實(shí)地用二維表格考阱,或者把多維表格降為二維翠忠。
Series和DataFrame的操作
可以把series理解為一列,dataframe可以理解為由很多個列(series)構(gòu)成的列乞榨。
我們可以像對待一個list一樣series秽之,完成各類操作
cities={'Beijing':55000,'Shanghai':60000,'Shenzhen':50000,'Hangzhou':20000,
'Guangzhou':45000,'Suzhou':None }
series5=pd.Series(cities**,name=**'incomes')
1)DataFrame描述性命令
info() #了解dataframe整體結(jié)構(gòu),列吃既,數(shù)據(jù)類型
describe() #了解數(shù)據(jù)分布
head()
tail()
2)訪問
2.1 Series切片訪問
series5[:5]
Beijing 55000.0
Guangzhou 45000.0
Hangzhou 20000.0
Shanghai 60000.0
Shenzhen 50000.0
Name: incomes, dtype: object
2.2 指定索引訪問考榨,注意這里位置可以任意調(diào)換
series5[[0,4,3,1,2]]
Beijing 55000.0
Shenzhen 50000.0
Shanghai 60000.0
Guangzhou 45000.0
Hangzhou 20000.0
Name: incomes, dtype: object
series5[['Shanghai','Suzhou']]
Shanghai 60000.0
Suzhou NaN
dtype: float64
3)元素檢查
3.1 in關(guān)鍵字观挎,類似于檢查元素是否在列表中一樣的操作
'Suzhou' in series5
True
'Nanjing' in series5
False
3.2 Get方法訪問松捉,如果指定的index不存在,則返回nan
series5.get('Suzhou')
nan
series5.get('Beijing')
55000.0
4)條件boolean indexing
conditions=(series5==60000)
conditions
Beijing False
Guangzhou False
Hangzhou False
Shanghai True
Shenzhen False
Suzhou False
Name: incomes, dtype: object
按條件進(jìn)行對series過濾后蔑歌,會得到一個boolean型變量組成的Series對象,叫做boolean**** indexing震叙。這個series可以傳遞作為條件掀鹅,過濾掉所有相應(yīng)位置為False的記錄,得到最終結(jié)果媒楼。
series5[conditions]
Shanghai 60000.0
Name: incomes, dtype: object
4.1 非空與非空值過濾
找出所有的空值 或 非空值 的 boolean indexing****#bool****條件
series5.notnull() #或-series5.isnull()
Beijing True
Guangzhou True
Hangzhou True
Shanghai True
Shenzhen True
Suzhou False
Name: incomes, dtype: bool
series5.isnull() #或-series5.notnull()
Beijing False
Guangzhou False
Hangzhou False
Shanghai False
Shenzhen False
Suzhou True
5)簡單數(shù)學(xué)運(yùn)算
5.1 求均值乐尊,中位數(shù),最大最小划址,
series5.mean()
46000.0
series5.median()
50000.0
series5[series5.isnull]=series5.mean()
#把空項(xiàng)填充為均值
6)元素賦值
6.1 指定Series的index賦值
series5['Shenzhen']=70000
series5['Shenzhen']
70000
6.2 按boolean indexing條件過濾后賦值
series5[series5<50000]=50001
series5
Beijing 55000.0
Guangzhou 50001.0
Hangzhou 50001.0
Shanghai 60000.0
Shenzhen 50000.0
Suzhou NaN
Name: incomes, dtype: float64
7)數(shù)學(xué)運(yùn)算
series5 0.5# 算開方科吭,列表可不支持這樣的操作昏滴,這也是pandas強(qiáng)大的地方
Beijing 234.520788
Guangzhou 223.609034
Hangzhou 223.609034
Shanghai 244.948974
Shenzhen 223.606798
Suzhou NaN
Name: incomes, dtype: float64
np.log(series5)
Beijing 10.915088
Guangzhou 10.819798
Hangzhou 10.819798
Shanghai 11.002100
Shenzhen 10.819778
Suzhou NaN
Name: incomes, dtype: float64
7.1 運(yùn)算->自動indexing對齊
Pandas有個強(qiáng)大的功能猴鲫,叫做對齊对人。我們新建兩個series,列的順序是不是對齊的,而且兩個series中都有另一個series中沒有項(xiàng)拂共,但依舊可以進(jìn)行運(yùn)算牺弄,結(jié)果為NaN
s1=pd.Series({'Beijing':55000,'Shanghai':60000,'Hangzhou':20000})
s2=pd.Series({'Shenzhen':50000,'Beijing':55000,'Shanghai':60000})
s1
Beijing 55000
Hangzhou 20000
Shanghai 60000
dtype: int64
s2
Beijing 55000
Shanghai 60000
Shenzhen 50000
dtype: int64
s1+s2
Beijing 110000.0
Hangzhou NaN
Shanghai 120000.0
Shenzhen NaN
dtype: float64
總結(jié):pa****ndas****自動對齊兩個series的index,進(jìn)行運(yùn)算宜狐。
更多訪問方式
1)loc
按indx取出Series,通過行標(biāo)簽索引行數(shù)據(jù),有標(biāo)簽時可以通過標(biāo)簽沒標(biāo)簽時可以通過行號势告。
df4.loc[0:2]
city population year bonus average
0 Beijing 2100 2016 6666 3.174286
1 Shanghai 2300 2017 6666 2.898261
2 Guangzhou 1000 2016 6666 6.666000
df4.loc[[0,3],['city','average']]
# 前邊 [0,3]代表選行,[‘city’,’average’]代表選列
city average
0 Beijing 3.174286
3 Shenzhen 9.522857
df4.loc[df4.average>10,['city','average']]
#前邊代表按列條件去過濾后剩下的行抚恒,['city', 'average']代表選列
2)iloc
只能通過數(shù)字索引獲來取數(shù)據(jù)
df4.iloc[1:,1:]
population year
1 2300 NaN
2 1000 2016.0
3 700 2017.0
4 500 2016.0
5 500 2016.0
3)Ix
混合索引咱台,可以和標(biāo)簽,索引俭驮,行號混用回溺。
*df4.ix[:4,['city','population']]*
city population
0 Beijing 2100
1 Shanghai 2300
2 Guangzhou 1000
3 Shenzhen 700
4 Hangzhou 500
4)條件組合與判斷訪問
4.1 條件組合
(df4.population==2100)|(df4.population==1000)
0 True
1 False
2 True
3 False
4 False
5 False
df4.loc[((df4.population==2100)|(df4.population==1000)),:]
city population year
0 Beijing 2100 2016
2 Guangzhou 1000 2016
4.2 指定條件
df4.population.isin([2100,1000])
0 True
1 False
2 True
3 False
4 False
5 False
可以看到,使用isin函數(shù)得到的是一個boolean indexing
Pandas里的條件否定混萝,可以簡單前邊加一個負(fù)號即可遗遵。
df4.population.isin([2100,1000])
0 False
1 True
2 False
3 True
4 True
5 True
Name: population, dtype: bool
df4.loc[df4.population.isin([2100,1000]),:]
# isin 的傳入?yún)?shù)可以是一個列表,ndarray,Series
city population year
0 Beijing 2100 2016
2 Guangzhou 1000 2016
5)缺省值與缺少值填充
缺少值的類型是numpy中的nan
df4.iloc[1,2]=np.nan
city population year
0 Beijing 2100 2016.0
1 Shanghai 2300 NaN
2 Guangzhou 1000 2016.0
3 Shenzhen 700 2017.0
4 Hangzhou 500 2016.0
5 Chongqi 500 2016.0
df4.fillna(2017)
#注意此時是返回一個修過的df,而原來的df不會被修改
如果要修改原來的df,指定inplace=True*
city population year
0 Beijing 2100 2016.0
1 Shanghai 2300 2017.0
2 Guangzhou 1000 2016.0
3 Shenzhen 700 2017.0
4 Hangzhou 500 2016.0
5 Chongqi 500 2016.0
高級填充
如果是像天氣逸嘀,股票價格的取樣周期很短车要,如每半分鐘一次的的數(shù)據(jù),缺少值就適合用這種方法填充崭倘。但同樣的場景翼岁,每半小時取樣,就不適用這種方法了司光。先分析場景很重要琅坡。
df4.fillna(method='ffill') #按空值前一值填充
df4.fillna(method='bfill') #按空值后一值填充
廣播特性Broadcasting
df4=pd.DataFrame(population)
df4['bonus']=6666
df4#這里的6666為標(biāo)量,要應(yīng)用到整個series飘庄,脑蠕,就會使用到廣播
df4
city population year bonus
0 Beijing 2100 2016 6666
1 Shanghai 2300 2017 6666
2 Guangzhou 1000 2016 6666
3 Shenzhen 700 2017 6666
4 Hangzhou 500 2016 6666
5 Chongqi 500 2016 6666
并行進(jìn)行的廣播,非循環(huán)
df4['average']=df4['bonus']/df4['population']
df4
city population year bonus average
0 Beijing 2100 2016 6666 3.174286
1 Shanghai 2300 2017 6666 2.898261
2 Guangzhou 1000 2016 6666 6.666000
3 Shenzhen 700 2017 6666 9.522857
4 Hangzhou 500 2016 6666 13.332000
5 Chongqi 500 2016 6666 13.332000
簡單繪畫
from matplotlib import pyplot as plt
df4.population.plot(kind='bar')
matplotlib.axes._subplots.AxesSubplot object at 0x0000012F67F09E80
plt.show()
寫在最后
本篇筆記偏Pandas基礎(chǔ)入門及介紹跪削,課后留的作業(yè)要遠(yuǎn)比筆記涉及的多谴仙,要難。在第二篇筆記中將記錄這些Pandas高級應(yīng)用碾盐,將在公眾號上整理發(fā)布晃跺,同學(xué)們敬請期待。
python筆記:
Python數(shù)據(jù)分析之:numpy入門(一)
Python數(shù)據(jù)分析之:numpy入門(二)
Python數(shù)據(jù)分析之:numpy入門(三)
Python數(shù)據(jù)分析之:numpy入門(四)