pandas

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 的大部分開發工作都集中在表格型數據上,所以這些事數據更常見。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容