pandas 入門
pandas 的數據結構介紹
pandas 有兩個重要的數據結構:Series和DataFrame。
Series
Series是一個一維的類似的數組對象,包含一個數組的數據(任何NumPy的數據類型)和一個與數組關聯的數據標簽,被叫做 索引 。
obj = Series([4, 7, -5, 3])
obj
Ou:
0 4
1 7
2 -5
3 3
# 如果沒有給數據指定索引,一個包含整數0到 N-1 (這里N是數據的長度)的默認索引被創建。
obj.values
Out: array([ 4, 7, -5, 3])
obj.index
Out: Int64Index([0, 1, 2, 3])
obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2
Out:
d 4
b 7
a -5
c 3
Series是一個定長的有序的字典,因為它把索引和值映射起來了。
'b' in obj2
Out: True
'e' in obj2
Out: False
可以通過傳遞一個 Python 字典來創建一個 Series:
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = Series(sdata)
obj3
Out: # 結果是按照索引排序后的順序
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000113
states = [‘California’, ‘Ohio’, ‘Oregon’, ‘Texas’]
obj4 = Series(sdata, index=states)
obj4
Out:
California NaN
Ohio 35000
Oregon 16000
Texas 71000
在這種情況下, sdata 中的3個值被放在了合適的位置,但因為沒有發現對應于 ‘California’ 的值,就出現了 NaN (不是一個數),這在pandas中被用來標記數據缺失或 NA 值。我使用“missing”或“NA”來表示數度丟失。在pandas中用函數 isnull 和 notnull 來檢測數據丟失:
pd.isnull(obj4) # 或者使用實例方法obj4.isnull()
Out[26]:
California True
Ohio False
Oregon False
Texas False
Series的一個重要的功能是:它在運算中會自動對齊不同索引的數據。
obj3 + obj4
Out:
California NaN
Ohio 70000
Oregon 32000
Texas 142000
Utah NaN
Series對象本身和它的索引都有一個 name 屬性,它和pandas的其它一些關鍵功能整合在一起:
obj4.name = 'population'
obj4.index.name = 'state'
obj4
Out:
state
California NaN
Ohio 35000
Oregon 16000
Texas 71000
Name: population
DataFrame
一個Datarame表示一個表格,類似電子表格的數據結構,包含一個經過排序的列表集,它們沒一個都可以有不同的類型值(數字,字符串,布爾等等)。
有很多方法來構建一個DataFrame,但最常用的一個是用一個相等長度列表的字典或NumPy數組:
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = DataFrame(data)
frame
Out:
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
如果你設定了一個列的順序,DataFrame的列將會精確的按照你所傳遞的順序排列;和Series一樣,如果你傳遞了一個行,但不包括在 data 中,在結果中它會表示為NA值:
frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
....: index=['one', 'two', 'three', 'four', 'five'])
frame2
Out:
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN
和Series一樣,在DataFrame中的一列可以通過字典記法或屬性來檢索:
frame2['state'] # 或是使用屬性 frame2.state
Out:
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
Name: state
# 注意,返回的Series包含和DataFrame相同的索引,并它們的 name 屬性也被正確的設置了。
給一個不存在的列賦值,將會創建一個新的列。 像字典一樣 del 關鍵字將會刪除列。==索引DataFrame時返回的列是底層數據的一個視窗,而不是一個拷貝。因此,任何在Series上的就地修改都會影響DataFrame。列可以使用Series的 copy 函數來顯式的拷貝。==
另一種通用的數據形式是一個嵌套的字典的字典格式,如果被傳遞到DataFrame,它的外部鍵會被解釋為列索引,內部鍵會被解釋為行索引::
pop = {'Nevada': {2001: 2.4, 2002: 2.9},
....: 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = DataFrame(pop)
frame3
Out:
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
可以輸入給 DataFrame 構造器的數據
類型 | 說明 |
---|---|
二維ndarray | 一個數據矩陣,有可選的行標和列標 |
數組,列表或元組的字典 | 每一個序列成為DataFrame中的一列。所有的序列必須有相同的長度。 |
NumPy的結構/記錄數組 | 和“數組字典”一樣處理 |
Series的字典 | 每一個值成為一列。如果沒有明顯的傳遞索引,將結合每一個Series的索引來形成結果的行索引。 |
字典的字典 | 每一個內部的字典成為一列。和“Series的字典”一樣,結合鍵值來形成行索引。 |
字典或Series的列表 | 每一項成為DataFrame中的一列。結合字典鍵或Series索引形成DataFrame的列標。 |
列表或元組的列表 | 和“二維ndarray”一樣處理 |
另一個DataFrame | DataFrame的索引將被使用,除非傳遞另外一個 |
NumPy偽裝數組(MaskedArray) | 除了掩碼值在DataFrame中成為NA/丟失數據之外,其它的和“二維ndarray”一樣 |
DataFrame的 index 和 columns 有它們的 name,可以顯示調用;跟 Series 一樣,values 屬性返回一個包含在 DataFrame 中的數據的二維 ndarray。
索引對象
pandas的索引對象用來保存坐標軸標簽和其它元數據(如坐標軸名或名稱)。構建一個Series或DataFrame時任何數組或其它序列標簽在內部轉化為索引:
obj = Series(range(3), index=['a', 'b', 'c'])
index = obj.index
index
Out: Index([a, b, c], dtype=object)
index[1:]
Out: Index([b, c], dtype=object)
索引對象是不可變的,因此不能由用戶改變;索引對象的不可變性非常重要,這樣它可以在數據結構中結構中安全的共享。
index[1] = 'd' # 錯誤
index = pd.Index(np.arange(3))
obj2 = Series([1.5, -2.5, 0], index=index)
obj2.index is index
Out: True
每個索引都有許多關于集合邏輯的方法和屬性,且能夠解決它所包含的數據的常見問題。
索引方法和屬性
方法 | 說明 |
---|---|
append | 鏈接額外的索引對象,產生一個新的索引 |
diff | 計算索引的差集 |
intersection | 計算交集 |
union | 計算并集 |
isin | 計算出一個布爾數組表示每一個值是否包含在所傳遞的集合里 |
delete | 計算刪除位置i的元素的索引 |
drop | 計算刪除所傳遞的值后的索引 |
insert | 計算在位置i插入元素后的索引 |
is_monotonic | 返回True,如果每一個元素都比它前面的元素大或相等 |
is_unique | 返回True,如果索引沒有重復的值 |
unique | 計算索引的唯一值數組 |
基本功能
主要是操作 Series 和 DataFrame 中的數據的基本手段。
重新索引
pandas對象的一個關鍵的方法是 reindex ,創建一個適應新索引的新對象。
obj = Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
Out:
d 4.5
b 7.2
a -5.3
c 3.6
在Series上調用 reindex 重排數據,使得它符合新的索引,如果那個索引的值不存在就引入缺失數據值:
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
Out:
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
Out:
a -5.3
b 7.2
c 3.6
d 4.5
e 0.0
為了對時間序列這樣的數據排序,當重建索引的時候可能想要對值進行內插或填充。 method 選項可以是你做到這一點,使用一個如 ffill 的方法來向前填充值:
obj3 = Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3.reindex(range(6), method='ffill')
Out:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
參數 | 描述 |
---|---|
ffill或pad | 前向填充(或搬運)值 |
bfill或backfill | 后向填充(或搬運)值 |
reindex 的(插值)method 選項
參數 | 描述 |
---|---|
ffill或pad | 前向填充(或搬運)值 |
bfill或backfill | 后向填充(或搬運)值 |
對于DataFrame, reindex 可以改變(行)索引,列或兩者。當只傳入一個序列時,結果中的行被重新索引了:
frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'],
....: columns=['Ohio', 'Texas', 'California'])
frame
Out:
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
In [89]: frame2
Out[89]:
Ohio Texas California
a 0 1 2
b NaN NaN NaN
c 3 4 5
d 6 7 8
# 使用columns關鍵字指定列重新索引
states = ['Texas', 'Utah', 'California']
In [91]: frame.reindex(columns=states)
Out[91]:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8
一次可以對兩個重新索引,可是插值只在行側(0坐標軸)進行:
frame.reindex(index=['a', 'b', 'c', 'd'], method='ffill',
....: columns=states)
Out:
Texas Utah California
a 1 NaN 2
b 1 NaN 2
c 4 NaN 5
d 7 NaN 8
使用帶標簽索引的 ix 可以把重新索引做的更簡單:
frame.ix[['a', 'b', 'c', 'd'], states]
Out:
Texas Utah California
a 1 NaN 2
b NaN NaN NaN
c 4 NaN 5
d 7 NaN 8
reindex 函數的參數
參數 | 說明 |
---|---|
index | 作為索引的新序列。可以是索引實例或任何類似序列的Python數據結構。一個索引被完全使用,沒有任何拷貝。 |
method | 插值(填充)方法,見上表。 |
fill_value | 代替重新索引時引入的缺失數據值 |
limit | 當前向或后向填充時,最大的填充間隙 |
level | 在多層索引上匹配簡單索引,否則選擇一個子集 |
copy | 如果新索引與就的相等則底層數據不會拷貝。默認為True(即始終拷貝) |
丟棄指定軸上的項
從坐標軸刪除一個多或多個條目是很容易的,如果你有一個索引數組或列表且沒有這些條目,但是這可能需要一點修改和集合邏輯。 drop 方法將會返回一個新的對象并從坐標軸中刪除指定的一個或多個值:
obj = Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
new_obj = obj.drop('c')
new_obj
Out:
a 0
b 1
d 3
e 4
obj.drop(['d', 'c'])
Out:
a 0
b 1
e 4
對于DataFrame,可以從任何坐標軸刪除索引值。如 data.drop('a',axis = 0)。
索引、選取和過濾
Series索引( obj[...] )的工作原理類似與NumPy索引,除了可以使用Series的索引值,也可以僅使用整數來索引。使用索引來切片和正常的Python切片并不一樣,會包含結束點。
索引DataFrame來檢索一個或多個列,可以使用一個單一值或一個序列:
data = DataFrame(np.arange(16).reshape((4, 4)),
.....: index=['Ohio', 'Colorado', 'Utah', 'New York'],
.....: columns=['one', 'two', 'three', 'four'])
data
Out:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
data['two'] data[['three', 'one']]
Out: Out:
Ohio 1 three one
Colorado 5 Ohio 2 0
Utah 9 Colorado 6 4
New York 13 Utah 10 8
Name: two New York 14 12
可以通過切片或一個布爾數組來選擇行:
data[:2] data[data['three'] > 5]
Out: Out:
one two three four one two three four
Ohio 0 1 2 3 Colorado 4 5 6 7
Colorado 4 5 6 7 Utah 8 9 10 11
New York 12 13 14 15
在索引中使用一個布爾DataFrame,例如通過純量比較產生的:
data < 5
| 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
索引字段 ix 可以從DataFrame選擇一個行和列的子集,使用像NumPy的記法再加上軸標簽。
data.ix['Colorado',['two','three']] # 或使用 data.ix['Colorado',[1,2]]
Out:
two 5
three 6
Name: Colorado
data.ix[:'Utah','two']
Out:
Ohio 0
Colorado 5
Utah 9
Name: two
data.ix[data.three > 5, :3]
Out:
one two three
Colorado 4 5 6
Utah 8 9 10
New York 12 13 14
DataFrame 的索引選項
類型 | 說明 |
---|---|
obj[val] | 從DataFrame選擇單一列或連續列。特殊情況下的便利:布爾數組(過濾行),切片(行切片),或布爾DataFrame(根據條件設置值)。 |
obj.ix[val] | 從DataFrame的行集選擇單行 |
obj.ix[:, val] | 從列集選擇單列 |
obj.ix[val1, val2] | 選擇行和列 |
reindex 方法 | 轉換一個或多個軸到新的索引 |
xs 方法 | 通過標簽選擇單行或單列到一個Series |
icol, irow 方法 | 通過整數位置,分別的選擇單行或單列到一個Series |
get_value, set_value 方法 | 通過行和列標選擇一個單值 |
算術運算和數據對齊
pandas的最重要的特性之一是在具有不同索引的對象間進行算術運算的行為。當把對象加起來時,如果有任何的索引對不相同的話,在結果中將會把各自的索引聯合起來。內部數據對其,在索引不重合的地方引入了NA值。
在算術方法中填充值
在不同索引對象間的算術運算,當一個軸標簽在另一個對象中找不到時,你可能想要填充一個特定的值,如0:
df1 = DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))
df2 = DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))
df1 + df2
把它們加起來導致在不重合的位置出現NA值:
| a | b | c | d | e
--- | --- | --- | --- | --- | ---
0 | 0 | 2 | 4 | 6 | NaN
1 | 9 | 11 | 13 | 15 | NaN
2 | 18 | 20 | 22 | 24 | NaN
3 | NaN | NaN | NaN | NaN | NaN
在 df1 上使用 add 方法,我把 df2 傳遞給它并給 fill_value 賦了一個參數:
df1.add(df2,fill_value=0)
| a | b | c | d | e
--- | --- | --- | --- | --- | ---
0 | 0 | 2 | 4 | 6 | 4
1 | 9 | 11 | 13 | 15 | 9
2 | 18 | 20 | 22 | 24 | 14
3 | 15 | 16 | 17 | 18 | 19
靈活的算術方法
方法 | 說明 |
---|---|
add | 加法(+) |
sub | 減法(-) |
div | 除法(/) |
mul | 乘法(*) |
DataFrame 和 Series 之間的運算
DataFrame和Series間的算術運算Series的索引將匹配DataFrame的列,并在行上擴展。如果一個索引值在DataFrame的列和Series的索引里都找不著,對象將會從它們的聯合重建索引。如果想在行上而不是列上進行擴展,你要使用一個算術方法。例如:
frame = DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
| b | d | e
--- | --- | --- | ---
Utah | 0 | 1 | 2
Ohio | 3 | 4 | 5
Texas | 6 | 7 | 8
Oregon | 9 | 10 | 11
series = frame['d']
frame.sub(series, axis=0)
| b | d | e
--- | --- | --- | ---
Utah | -1 | 0 | 1
Ohio | -1 | 0 | 1
Texas | -1 | 0 | 1
Oregon | -1 | 0 | 1
函數應用和映射
NumPy 的 ufuncs(元素級數組方法)也可以用于操作 pandas 對象:
frame = DataFrame(np.random.randn(4, 3), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
Out:
b d e
Utah -0.204708 0.478943 -0.519439
Ohio -0.555730 1.965781 1.393406
Texas 0.092908 0.281746 0.769023
Oregon 1.246435 1.007189 -1.296221
np.abs(frame) # frame 的元素的絕對值
Out:
b d e
Utah 0.204708 0.478943 0.519439
Ohio 0.555730 1.965781 1.393406
Texas 0.092908 0.281746 0.769023
Oregon 1.246435 1.007189 1.296221
將函數應用到由各列或行所形成的一維數組上。DataFrame 的 apply 方法既可以實現此功能:
f = lambda x: x.max() - x.min()
frame.apply(f)
Out:
b 1.802165
d 1.684034
e 2.689627
dtype: float64
frame.apply(f, axis=1)
Out:
Utah 0.998382
Ohio 2.521511
Texas 0.676115
Oregon 2.542656
dtype: float64
許多最為常見的數組統計方法都被實現成 DataFrame 方法(如 sum 和 mean),因此無須使用 apply 方法。
除標量值外,傳遞給 apply 的函數還可以返回由多個值組成的 Series:
def f(x):
return Series([x.min(), x.max()], index=['min', 'max'])
frame.apply(f)
Out:
b d e
min -0.555730 0.281746 -1.296221
max 1.246435 1.965781 1.393406
此外,元素級的 Python 函數也是可以用的。要得到 frame 中各個浮點值的格式化字符串,使用 applymap (之所以叫 applymap ,是因為 Series 有一個用于應用元素級函數的 map 方法)即可:
format = lambda x: '%.2f' % x
frame.applymap(format)
Out:
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
frame['e'].map(format)
Out:
Utah -0.52
Ohio 1.39
Texas 0.77
Oregon -1.30
Name: e, dtype: object
排序和排名
根據條件對數據集排序(sorting)也是一種重要的內置運算。
對 Series 用sort_index方法排序:
obj = Series(range(4), index=['d', 'a', 'b', 'c'])
obj.sort_index()
Out:
a 1
b 2
c 3
d 0
dtype: int64
對于 DataFrame,則可以根據任意一個軸上的索引進行排序:
frame = DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'],
columns=['d', 'a', 'b', 'c'])
frame.sort_index()
Out:
d a b c
one 4 5 6 7
three 0 1 2 3
數據默認是生序排序的,但也可以將序排序:
frame.sort_index(axis=1, ascending=False)
Out:
d c b a
three 0 3 2 1
one 4 7 6 5
按值對 Series 進行排序,可以使用 order 方法:
obj = Series([4, 7, -3, 2])
obj.order()
Out:
2 -3
3 2
0 4
1 7
dtype: int64
在 DataFrame 上,可以根據一個或多個列中的值進行排序,將一個或多個列的名字傳遞給 by 選項即可:
frame = DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame.sort_index(by=['a', 'b'])
Out:
a b
2 0 -3
0 0 4
3 1 2
1 1 7
排名跟排序關系密切,且它會增設一個排名值(從1開始,一直到數組中有效數據的數量)。它跟 numpy.argsort 產生的間接排序索引差不多,只不過它可以根據某種規則破壞平級關系。
默認情況下,rank 是通過“為各組分配一個平均排名”的方式破壞平級關系:
obj = Series([7, -5, 7, 4, 2, 0, 4])
obj.rank()
Out:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
也可以根據值在原數據中出現的順序給出排名:
obj.rank(method='first')
Out:
0 6
1 1
2 7
3 4
4 3
5 2
6 5
dtype: float64
排名時用于破壞平級關系的 method 選項
method | 說明 |
---|---|
average | 默認:在相等分組中,為各個值分配平均排名 |
min | 使用整個分組的最小排名 |
max | 使用整個分組的最大排名 |
first | 按值在原始數據中的出現吮吸分配排名 |
帶有重復值的軸索引
索引的 is_unique 屬性可以查看索引值是否唯一。
如果某個索引對應多個值,則返回一個 Series;而對應單個值得,則返回一個標量值。對 DataFrame 的行進行索引時也是如此。
匯總和計算描述統計
pandas 對象擁有一組常用的數學和統計方法。它們大部分都屬于約簡和匯總統計,用于從 Series 中提取單個值(如 sum 或 mean)或從 DataFrame 的行貨列中提取一個 Series。跟對應的 Numpy 數組方法相比,它們都是基于沒有缺失數據的假設而構建的。
描述和匯總統計
方法 | 說明 |
---|---|
count | 非 NA 值的數量 |
describe | 針對 Series 或 DataFrame 的列計算匯總統計 |
min , max | 最小值和最大值 |
argmin , argmax | 最小值和最大值的索引位置(整數) |
idxmin , idxmax | 最小值和最大值的索引值 |
quantile | 樣本分位數(0 到 1) |
sum | 求和 |
mean | 均值 |
median | 中位數 |
mad | 根據均值計算平均絕對離差 |
var | 方差 |
std | 標準差 |
skew | 樣本值的偏度(三階矩) |
kurt | 樣本值的峰度(四階矩) |
cumsum | 樣本值的累計和 |
cummin , cummax | 樣本值的累計最大值和累計最小值 |
cumprod | 樣本值的累計積 |
diff | 計算一階差分(對時間序列很有用) |
pct_change | 計算百分數變化 |
相關系數和協方差
Series 的 corr 和 cov 方法用于計算兩個 Series 中重疊的、非NA的、按索引對齊的值得相關系數和協方差。
DataFrame 的 corr 和 cov 方法將以 DataFrame 的形式返回完整的相關系數或協方差矩陣。
DataFrame 的 corrwith 方法可以計算其列或行跟另一個 Series 或 DataFrame 之間的相關系數。
唯一值、值計算以及成員資格
唯一值、值計數和成員資格方法
方法 | 說明 |
---|---|
isin | 計算一個表示“Series 各值是否包含于傳入的值序列中”的布爾型數組 |
unique | 計算 Series 中的唯一值數組,按發現的順序返回 |
value_counts | 返回一個 Series,其索引為唯一值,其值為計數,降序排列 |
將pandas.value_counts 傳給 DataFrame 的 apply 函數:
data = DataFrame({'Qu1': [1, 3, 4, 3, 4],
'Qu2': [2, 3, 1, 2, 3],
'Qu3': [1, 5, 2, 4, 4]})
data
Out:
Qu1 Qu2 Qu3
0 1 2 1
1 3 3 5
2 4 1 2
3 3 2 4
4 4 3 4
result = data.apply(pd.value_counts).fillna(0)
result
Out:
Qu1 Qu2 Qu3
1 1 1 1
2 0 2 1
3 2 2 0
4 2 0 2
5 0 0 1
處理缺失數據
NA 處理方法
方法 | 說明 |
---|---|
dropna | 根據各標簽的值中是否存在缺失數據對軸標簽進行過濾,可通過閥值調節對缺失值的容忍度 |
fillna | 用指定值或插值方法(如 ffill 或 bfill)填充缺失數據 |
isnull | 返回一個含有布爾值得對象,這些布爾值表示哪些值是缺失值,該對象的類型與源類型一樣 |
notnull | isnull的否定式 |
濾除缺失數據
對于 DataFrame 對象,dropna 默認丟棄任何含有缺失值的行:
data = DataFrame([[1., 6.5, 3.], [1., NA, NA],
[NA, NA, NA], [NA, 6.5, 3.]])
cleaned = data.dropna()
data
Out:
0 1 2
0 1 6.5 3
1 1 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3
cleaned
Out:
0 1 2
0 1 6.5 3
傳入 how = 'all' 將只丟棄全為 NA 的那些行:
data.dropna(how='all')
Out:
0 1 2
0 1 6.5 3
1 1 NaN NaN
3 NaN 6.5 3
填充缺失數據
fillna 方法是主要的填充函數。
通過一個字典調用 fillna,可以實現對不同的列填充不同的值:
df = DataFrame(np.random.randn(7, 3))
df.ix[:4, 1] = NA; df.ix[:2, 2] = NA
df
Out:
0 1 2
0 0.274992 NaN NaN
1 0.886429 NaN NaN
2 1.669025 NaN NaN
3 0.476985 NaN -1.021228
4 -0.577087 NaN 0.302614
5 0.523772 0.000940 1.343810
6 -0.713544 -0.831154 -2.370232
df.fillna({1: 0.5, 3: -1})
Out:
0 1 2
0 0.274992 0.500000 NaN
1 0.886429 0.500000 NaN
2 1.669025 0.500000 NaN
3 0.476985 0.500000 -1.021228
4 -0.577087 0.500000 0.302614
5 0.523772 0.000940 1.343810
6 -0.713544 -0.831154 -2.370232
fillna 函數的參數
參數 | 說明 |
---|---|
value | 用于填充缺失值的標量值或字典對象 |
method | 插值方式。如果函數調用時未指定其他參數的話,默認為“ffill” |
axis | 待填充的軸,默認axis = 0 |
inplace | 修改調用者對象而不產生副本 |
limit | 可以連續填充的最大數量 |
層次化索引
層次化索引時 pandas 的一項重要功能,它是你能在一個軸上擁有多個索引級別。
data = Series(np.random.randn(10),
index=[['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd'],
[1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
data
Out:
a 1 -0.204708
2 0.478943
3 -0.519439
b 1 -0.555730
2 1.965781
3 1.393406
c 1 0.092908
2 0.281746
d 2 0.769023
3 1.246435
dtype: float64
data.index
Out:
MultiIndex(levels=[[u'a', u'b', u'c', u'd'], [1, 2, 3]],
labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])
層次化索引在數據重塑和基于分組的操作(如透視表生成)中扮演著重要角色。如 data 可以通過其 unstack 方法被重新安排到一個 DataFrame 中:
data.unstack()
Out:
1 2 3
a -0.204708 0.478943 -0.519439
b -0.555730 1.965781 1.393406
c 0.092908 0.281746 NaN
d NaN 0.769023 1.246435
# unstack 的逆運算是 stack。
對于一個 DataFrame,每條軸都可以有分層索引:
frame = DataFrame(np.arange(12).reshape((4, 3)),
index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
columns=[['Ohio', 'Ohio', 'Colorado'],
['Green', 'Red', 'Green']])
frame.index.names = ['key1', 'key2']
frame.columns.names = ['state', 'color']
frame
Out:
state Ohio Colorado
color Green Red Green
key1 key2
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
重排分級順序
swaplevel 接受兩個級別編號或名稱,并返回一個互換了級別的新對象:
frame.swaplevel('key1', 'key2')
Out:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
2 a 3 4 5
1 b 6 7 8
2 b 9 10 11
sortlevel 根據單個級別中的值對數據進行排序。
frame.swaplevel(0, 1).sortlevel(0)
Out:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
b 6 7 8
2 a 3 4 5
b 9 10 11
根據級別匯總統計
許多對 DataFrame 和 Series 的描述和匯總統計都有一個 level 選項,它用于指定某條周上求和的級別。
frame.sum(level='color', axis=1)
Out:
color Green Red
key1 key2
a 1 2 1
2 8 4
b 1 14 7
2 20 10
# 這其實利用了 pandas 的 groupby 功能。
使用 DataFrame 的列
DataFrame 的 set_index 函數可以將 DataFrame 的一個或多個列當做行索引來用,而 reset_index 函數則是將行索引變成 DataFrame 的列。
frame = DataFrame({'a': range(7), 'b': range(7, 0, -1),
'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
'd': [0, 1, 2, 0, 1, 2, 3]})
frame
Out:
a b c d
0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
3 3 4 two 0
4 4 3 two 1
5 5 2 two 2
6 6 1 two 3
frame2 = frame.set_index(['c', 'd']) # 可以加入參數 drop=False 保留數據中的c、d列。
frame2
Out:
a b
c d
one 0 0 7
1 1 6
2 2 5
two 0 3 4
1 4 3
2 5 2
3 6 1
frame2.reset_index()
Out:
c d a b
0 one 0 0 7
1 one 1 1 6
2 one 2 2 5
3 two 0 3 4
4 two 1 4 3
5 two 2 5 2
6 two 3 6 1
其他有關 pandas 的話題
整數索引
操作由整數索引的 pandas 對象跟內置的 Python 數據結構(如列表和元組)在索引語義上有些不同。例如:
ser = Series(np.arange(3.))
ser[-1]
==會產生錯誤。==
對于一個非整數索引,就沒有問題。為了保持良好的一致性,盡量保持操作時面向標簽的,同樣包括用 ix 進行切片。如果需要可靠的、不考慮索引類型的、基于位置的索引,可以使用 Series 的 iloc 或 iat 方法和 DataFrame 的 irow 和 icol 方法:
ser.iloc[-1]
Out:
2.0
frame = DataFrame(np.arange(6).reshape((3, 2)), index=[2, 0, 1])
frame.iloc[0]
Out:
0 0
1 1
Name: 2, dtype: int32
面板數據
pandas 有一個 Panel 數據結構,可以將其看作一個三維版的 DataFrame。pandas 的大部分開發工作都集中在表格型數據上,所以這些事數據更常見。