根據(jù)《利用python進(jìn)行數(shù)據(jù)分析》第五章及原博文http://www.itdecent.cn/p/161364dd0acf的個(gè)人使用學(xué)習(xí)筆記
pandas數(shù)據(jù)結(jié)構(gòu)
Series
Series是一種類似于一維數(shù)組的對(duì)象,由一組數(shù)組(NumPy數(shù)據(jù)類型)以及一組與之相關(guān)的數(shù)據(jù)標(biāo)簽(即索引)組成。
In [11]: obj = pd.Series([4, 7, -5, 3])
?
In [12]: obj
Out[12]:
0 4
1 7
2 -5
3 3
dtype: int64
- 屬性:values, index
In [15]: obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
?
In [16]: obj2
Out[16]:
d 4
b 7
a -5
c 3
dtype: int64
?
In [17]: obj2.index
Out[17]: Index(['d', 'b', 'a', 'c'], dtype='object')
?
In [42]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
?
In [43]: obj
Out[43]:
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64
對(duì)于Series,可以使用NumPy函數(shù)或類似NumPy的運(yùn)算(如根據(jù)布爾型數(shù)組進(jìn)行過濾、標(biāo)量乘法、應(yīng)用數(shù)學(xué)函數(shù)等),同時(shí)會(huì)保留索引值的鏈接
可以看成定長的有序字典,也可以直接通過這個(gè)字典來創(chuàng)建Series
pandas的isnull和notnull函數(shù)可用于檢測(cè)缺失數(shù)據(jù)
Series對(duì)象本身及其索引都有一個(gè)name屬性
In [38]: obj4.name = 'population'
?
In [39]: obj4.index.name = 'state'
?
In [40]: obj4
Out[40]:
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64
DataFrame
DataFrame是一個(gè)表格型的數(shù)據(jù)結(jié)構(gòu),含有一組有序的列,每列可以是不同的值類型(數(shù)值、字符串、布爾值等)
DataFrame構(gòu)造方法
- 直接傳入一個(gè)由等長列表或NumPy數(shù)組組成的字典
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002, 2003],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
- 傳入嵌套字典,外層字典的鍵作為列,內(nèi)層鍵則作為行索引
In [65]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},
....: 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
In [66]: frame3 = pd.DataFrame(pop)
?
In [67]: frame3
Out[67]:
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
- 傳入Series組成的字典

訪問與賦值
-
訪問:frame[column]適用于任何列的名,frame.column只有在列名是一個(gè)合理的Python變量名時(shí)適用,返回一個(gè)Series
通過索引方式返回的列只是相應(yīng)數(shù)據(jù)的視圖而已,并不是副本。對(duì)返回的Series所做的任何就地修改全都會(huì)反映到源DataFrame上。通過Series的copy方法即可指定復(fù)制列。
head方法
賦值:列可以通過賦值修改,賦上標(biāo)量或者數(shù)組或Series(必須含index),為不存在的列賦值會(huì)創(chuàng)建出一個(gè)新列
In [58]: val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
?
In [59]: frame2['debt'] = val
?
In [60]: frame2
Out[60]:
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7
six 2003 Nevada 3.2 NaN`
其他屬性與方法
- del方法
In [63]: del frame2['eastern']
?
In [64]: frame2.columns
Out[64]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
index, columns都有name等屬性
values屬性以二維ndarray的形式返回DataFrame中的數(shù)據(jù),如果DataFrame各列的數(shù)據(jù)類型不同,則值數(shù)組的dtype就會(huì)選用能兼容所有列的數(shù)據(jù)類型
In [75]: frame2.values
Out[75]:
array([[2000, 'Ohio', 1.5, nan],
[2001, 'Ohio', 1.7, -1.2],
[2002, 'Ohio', 3.6, nan],
[2001, 'Nevada', 2.4, -1.5],
[2002, 'Nevada', 2.9, -1.7],
[2003, 'Nevada', 3.2, nan]], dtype=object)
索引對(duì)象index
- 特點(diǎn):不可修改,可以重復(fù)

基本功能
重新索引reindex
創(chuàng)建一個(gè)新對(duì)象,它的數(shù)據(jù)符合新的索引
不是重新對(duì)index賦值,而是重排順序
如果某個(gè)索引值當(dāng)前不存在,就引入缺失值
In [91]: obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
?
In [92]: obj
Out[92]:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
In [93]: obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
?
In [94]: obj2
Out[94]:
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64
- 對(duì)于時(shí)間序列這樣的有序數(shù)據(jù),重新索引時(shí)可能需要做一些插值處理。method選項(xiàng)即可達(dá)到此目的,例如,使用ffill可以實(shí)現(xiàn)前向值填充
In [95]: obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
?
In [96]: obj3
Out[96]:
0 blue
2 purple
4 yellow
dtype: object
?
In [97]: obj3.reindex(range(6), method='ffill')
Out[97]:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object
- 列可以用columns關(guān)鍵字重新索引
In [102]: states = ['Texas', 'Utah', 'California']
?
In [103]: frame.reindex(columns=states)
Out[103]:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8

刪除drop
In [105]: obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
?
In [106]: obj
Out[106]:
a 0.0
b 1.0
c 2.0
d 3.0
e 4.0
dtype: float64
?
In [109]: obj.drop(['d', 'c'])
Out[109]:
a 0.0
b 1.0
e 4.0
dtype: float64
通過傳遞axis=1或axis='columns'可以刪除列的值
In [113]: data.drop('two', axis=1)
Out[113]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15
索引、選取和過濾
Series索引與普通python切片不同,其末端是包含的
對(duì)DataFrame進(jìn)行索引關(guān)鍵字可以獲取一個(gè)或多個(gè)列
對(duì)DataFrame進(jìn)行索引數(shù)字列表或布爾型數(shù)組可以獲取一個(gè)或多個(gè)行
還有類似numpy二維數(shù)組的語法
In [128]: data = pd.DataFrame(np.arange(16).reshape((4, 4)),
.....: index=['Ohio', 'Colorado', 'Utah', 'New York'],
.....: columns=['one', 'two', 'three', 'four'])
In [131]: data[['three', 'one']]
Out[131]:
three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12
In [132]: data[:2]
Out[132]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
?
In [133]: data[data['three'] > 5]
Out[133]:
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
?
In [134]: data < 5
Out[134]:
one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False
- 用軸標(biāo)簽loc,整數(shù)標(biāo)簽iloc可以類似NumPy的標(biāo)記選擇行、列
In [137]: data.loc['Colorado', ['two', 'three']]
Out[137]:
two 5
three 6
Name: Colorado, dtype: int64
In [138]: data.iloc[2, [3, 0, 1]]
Out[138]:
four 11
one 8
two 9
Name: Utah, dtype: int6

算數(shù)運(yùn)算和數(shù)據(jù)對(duì)齊
pandas可以對(duì)不同索引的對(duì)象進(jìn)行算術(shù)運(yùn)算。
在將對(duì)象相加時(shí),如果存在不同的索引對(duì),則結(jié)果的索引就是該索引對(duì)的并集。
自動(dòng)的數(shù)據(jù)對(duì)齊操作在不重疊的索引處引入了NA值。
In [150]: s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
?
In [151]: s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
.....: index=['a', 'c', 'e', 'f', 'g'])
?
In [152]: s1
Out[152]:
a 7.3
c -2.5
d 3.4
e 1.5
dtype: float64
?
In [153]: s2
Out[153]:
a -2.1
c 3.6
e -1.5
f 4.0
g 3.1
dtype: float64
In [154]: s1 + s2
Out[154]:
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
對(duì)于DataFrame,對(duì)齊操作會(huì)同時(shí)發(fā)生在行和列上
add方法,傳入df2以及一個(gè)fill_value參數(shù),當(dāng)一個(gè)對(duì)象中某個(gè)軸標(biāo)簽在另一個(gè)對(duì)象中找不到時(shí)填充一個(gè)特殊值
In [171]: df1.add(df2, fill_value=0)
Out[171]:
a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 5.0 13.0 15.0 9.0
2 18.0 20.0 22.0 24.0 14.0
3 15.0 16.0 17.0 18.0 19.0
- 常用算數(shù)方法,每個(gè)都有一個(gè)副本,以字母r開頭,它會(huì)翻轉(zhuǎn)參數(shù)。

DataFrame和Series之間的運(yùn)算
- 不同維度的NumPy數(shù)組運(yùn)算,每一行都會(huì)執(zhí)行這個(gè)操作。這就叫做廣播(broadcasting)
In [175]: arr = np.arange(12.).reshape((3, 4))
?
In [176]: arr
Out[176]:
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
?
In [177]: arr[0]
Out[177]: array([ 0., 1., 2., 3.])
?
In [178]: arr - arr[0]
Out[178]:
array([[ 0., 0., 0., 0.],
[ 4., 4., 4., 4.],
[ 8., 8., 8., 8.]])
DataFrame和Series之間的算術(shù)運(yùn)算會(huì)將Series的索引匹配到DataFrame的列,然后沿著行一直向下廣播
如果某個(gè)索引值在DataFrame的列或Series的索引中找不到,則參與運(yùn)算的兩個(gè)對(duì)象就會(huì)被重新索引以形成并集
In [179]: frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
.....: columns=list('bde'),
.....: index=['Utah', 'Ohio', 'Texas', 'Oregon'])
?
In [180]: series = frame.iloc[0]
?
In [181]: frame
Out[181]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
?
In [182]: series
Out[182]:
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64
In [183]: frame - series
Out[183]:
b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0
In [184]: series2 = pd.Series(range(3), index=['b', 'e', 'f'])
?
In [185]: frame + series2
Out[185]:
b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
Oregon 9.0 NaN 12.0 NaN
- 如果匹配行且在列上廣播,則必須使用算術(shù)運(yùn)算方法。
In [186]: series3 = frame['d']
?
In [187]: frame
Out[187]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
?
In [188]: series3
Out[188]:
Utah 1.0
Ohio 4.0
Texas 7.0
Oregon 10.0
Name: d, dtype: float64
?
In [189]: frame.sub(series3, axis='index')
# (axis='index' or axis=0)
Out[189]:
b d e
Utah -1.0 0.0 1.0
Ohio -1.0 0.0 1.0
Texas -1.0 0.0 1.0
Oregon -1.0 0.0 1.0
函數(shù)應(yīng)用和映射
NumPy的ufuncs(元素級(jí)數(shù)組方法)也可用于操作pandas對(duì)象
apply方法即可實(shí)現(xiàn)將函數(shù)應(yīng)用到由各列或行所形成的一維數(shù)組上
In [193]: f = lambda x: x.max() - x.min()
?
In [194]: frame.apply(f)
Out[194]:
b 1.802165
d 1.684034
e 2.689627
dtype: float64
函數(shù)f計(jì)算了一個(gè)Series的最大值和最小值的差,在frame的每列都執(zhí)行了一次
傳遞axis='columns'到apply,這個(gè)函數(shù)會(huì)在每行執(zhí)行
傳遞到apply的函數(shù)不是必須返回一個(gè)標(biāo)量,還可以返回由多個(gè)值組成的Series
元素級(jí)的Python函數(shù)也是可以用的,使用applymap即可,Series有一個(gè)用于應(yīng)用元素級(jí)函數(shù)的map方法
In [198]: format = lambda x: '%.2f' % x
?
In [199]: frame.applymap(format)
Out[199]:
b d e
Utah -0.20 0.48 -0.52
Ohio -0.56 1.97 1.39
Texas 0.09 0.28 0.77
Oregon 1.25 1.01 -1.30
?
In [200]: frame['e'].map(format)
Out[200]:
Utah -0.52
Ohio 1.39
Texas 0.77
Oregon -1.30
Name: e, dtype: object
排名和排序
sort方法
要對(duì)行或列索引進(jìn)行排序(按字典順序),可使用sort_index方法,sort_values方法,它將返回一個(gè)已排序的新對(duì)象,默認(rèn)是按升序排序的,缺失值默認(rèn)放末尾
對(duì)于DataFrame,sort_index可以根據(jù)任意一個(gè)軸上的索引進(jìn)行排序.將一個(gè)或多個(gè)列的名字傳遞給sort_values的by選項(xiàng),可以根據(jù)特定值排列
In [203]: frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
.....: index=['three', 'one'],
.....: columns=['d', 'a', 'b', 'c'])
?
In [206]: frame.sort_index(axis=1, ascending=False)
Out[206]:
d c b a
three 0 3 2 1
one 4 7 6 5
?
In [214]: frame.sort_values(by=['a', 'b'])
Out[214]:
a b
2 0 -3
0 0 4
3 1 2
1 1 7
rank方法
默認(rèn)通過“為各組分配一個(gè)平均排名”的方式破壞平級(jí)關(guān)系的
也可以根據(jù)值在原數(shù)據(jù)中出現(xiàn)的順序給出排名
In [215]: obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
In [216]: obj.rank()
Out[216]:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
?
In [218]: obj.rank(ascending=False, method='max')
Out[218]:
0 2.0
1 7.0
2 2.0
3 4.0
4 5.0
5 6.0
6 4.0
dtype: float64
In [221]: frame.rank(axis='columns')
Out[221]:
a b c
0 2.0 3.0 1.0
1 1.0 3.0 2.0
2 2.0 1.0 3.0
3 2.0 3.0 1.0

重復(fù)標(biāo)簽的軸索引
許多pandas函數(shù)(如reindex)都要求標(biāo)簽唯一,但這并不是強(qiáng)制性的
索引的is_unique屬性可以告訴你它的值是否是唯一的
如果某個(gè)索引對(duì)應(yīng)多個(gè)值,則返回一個(gè)Series;而對(duì)應(yīng)單個(gè)值的,則返回一個(gè)標(biāo)量值
匯總和計(jì)算描述統(tǒng)計(jì)
匯總統(tǒng)計(jì)
pandas對(duì)象擁有一組常用的數(shù)學(xué)和統(tǒng)計(jì)方法,大部分都屬于約簡和匯總統(tǒng)計(jì),用于從Series中提取單個(gè)值(如sum或mean)或從DataFrame的行或列中提取一個(gè)Series
調(diào)用DataFrame的sum方法將會(huì)返回一個(gè)含有列的和的Series,傳入axis='columns'或axis=1將會(huì)按行進(jìn)行求和運(yùn)算
NA值會(huì)自動(dòng)被排除,除非整個(gè)切片(這里指的是行或列)都是NA。通過skipna選項(xiàng)可以禁用該功能
In [230]: df = pd.DataFrame([[1.4, np.nan], [7.1, -4.5],
.....: [np.nan, np.nan], [0.75, -1.3]],
.....: index=['a', 'b', 'c', 'd'],
.....: columns=['one', 'two'])
?
In [231]: df
Out[231]:
one two
a 1.40 NaN
b 7.10 -4.5
c NaN NaN
d 0.75 -1.3
?
In [233]: df.sum(axis=1)
Out[233]:
a 1.40
b 2.60
c NaN
d -0.55

- 有些方法(如idxmin和idxmax)返回的是間接統(tǒng)計(jì)(比如達(dá)到最小值或最大值的索引)或累計(jì)型
In [235]: df.idxmax()
Out[235]:
one b
two d
dtype: object
?
In [236]: df.cumsum()
Out[236]:
one two
a 1.40 NaN
b 8.50 -4.5
c NaN NaN
d 9.25 -5.8
?
In [237]: df.describe()
Out[237]:
one two
count 3.000000 2.000000
mean 3.083333 -2.900000
std 3.493685 2.262742
min 0.750000 -4.500000
25% 1.075000 -3.700000
50% 1.400000 -2.900000
75% 4.250000 -2.100000
max 7.100000 -1.300000
?
In [238]: obj = pd.Series(['a', 'a', 'b', 'c'] * 4)
?
In [239]: obj.describe()
Out[239]:
count 16
unique 3
top a
freq 8
dtype: object

相關(guān)系數(shù)與協(xié)方差
- pct_change()方法用于計(jì)算百分?jǐn)?shù)變化
In [242]: returns = price.pct_change()
?
In [243]: returns.tail()
Out[243]:
AAPL GOOG IBM MSFT
Date
2016-10-17 -0.000680 0.001837 0.002072 -0.003483
2016-10-18 -0.000681 0.019616 -0.026168 0.007690
2016-10-19 -0.002979 0.007846 0.003583 -0.002255
2016-10-20 -0.000512 -0.005652 0.001719 -0.004867
2016-10-21 -0.003930 0.003011 -0.012474 0.042096
Series的corr方法用于計(jì)算兩個(gè)Series中重疊的、非NA的、按索引對(duì)齊的值的相關(guān)系數(shù),cov用于計(jì)算協(xié)方差
DataFrame的corr和cov方法將以DataFrame的形式分別返回完整的相關(guān)系數(shù)或協(xié)方差矩陣
DataFrame的corrwith方法可以計(jì)算其列或行跟另一個(gè)Series或DataFrame之間的相關(guān)系數(shù)。傳入一個(gè)Series將會(huì)返回一個(gè)相關(guān)系數(shù)值Series(針對(duì)各列進(jìn)行計(jì)算)
In [244]: returns['MSFT'].corr(returns['IBM'])
Out[244]: 0.49976361144151144
?
In [245]: returns['MSFT'].cov(returns['IBM'])
Out[245]: 8.8706554797035462e-05
In [247]: returns.corr()
Out[247]:
AAPL GOOG IBM MSFT
AAPL 1.000000 0.407919 0.386817 0.389695
GOOG 0.407919 1.000000 0.405099 0.465919
IBM 0.386817 0.405099 1.000000 0.499764
MSFT 0.389695 0.465919 0.499764 1.000000
?
In [248]: returns.cov()
Out[248]:
AAPL GOOG IBM MSFT
AAPL 0.000277 0.000107 0.000078 0.000095
GOOG 0.000107 0.000251 0.000078 0.000108
IBM 0.000078 0.000078 0.000146 0.000089
MSFT 0.000095 0.000108 0.000089 0.000215
?
In [249]: returns.corrwith(returns.IBM)
Out[249]:
AAPL 0.386817
GOOG 0.405099
IBM 1.000000
MSFT 0.499764
dtype: float64
唯一值、值計(jì)數(shù)以及成員資格
unique可以得到Series中的唯一值數(shù)組
可以對(duì)結(jié)果再次進(jìn)行排序(uniques.sort())
value_counts用于計(jì)算一個(gè)Series中各值出現(xiàn)的頻率
In [251]: obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
In [252]: uniques = obj.unique()
?
In [253]: uniques
Out[253]: array(['c', 'a', 'd', 'b'], dtype=object)
In [255]: pd.value_counts(obj.values, sort=False)
Out[255]:
a 3
b 2
c 3
d 1
dtype: int64
- isin用于判斷矢量化集合的成員資格,可用于過濾Series中或DataFrame列中數(shù)據(jù)的子集,返回布爾值Series