Pandas快速教程-必要的基本功能
一.資料的快速檢視head和tail
這兩個方法可以快速的檢視一組資料的小抽樣,預設的設定是5行,當然也可以設定要返回的數目.
t=df.head(2)
t
Out[134]:
First Secend Third
0 2.0 1.0 1
1 4.0 2.0 2
df.tail(3)
Out[135]:
First Secend Third
1 4.0 2.0 2
2 NaN 3.0 a
3 8.0 NaN b
二.二元操作
在pandas結構化資料的二元化操作中,有兩點是需要特別注意的:
1.從高緯資料向低維資料的廣播(broadcasting )
2.缺失值(Missing Value)的計算中的處理
DataFrame的add(),sub()等等二元函式方法實現了二元化的操作.對於DataFrame結構的資料的廣播方式來說,與Series物件進行計算的廣播是最常見的.在二元函式中,可以使用axis引數來控制廣播方向.
df Out[7]: one two three a 2.0 9 NaN b 6.0 5 1.0 c 5.0 8 6.0 d NaN 6 1.0 row=df.loc['b'] col=df['two'] df.sub(row,axis='columns') Out[20]: one two three a -4.0 4.0 NaN b 0.0 0.0 0.0 c -1.0 3.0 5.0 d NaN 1.0 0.0 df.sub(row,axis=1) Out[21]: one two three a -4.0 4.0 NaN b 0.0 0.0 0.0 c -1.0 3.0 5.0 d NaN 1.0 0.0 df.add(col,axis='index') Out[22]: one two three a 11.0 18.0 NaN b 11.0 10.0 6.0 c 13.0 16.0 14.0 d NaN 12.0 7.0 df.add(col,axis=0) Out[23]: one two three a 11.0 18.0 NaN b 11.0 10.0 6.0 c 13.0 16.0 14.0 d NaN 12.0 7.0
對於多級索引的資料來說,可以增加一個level引數以控制層級
df_mul=df.copy() df_mul.index=pd.MultiIndex.from_tuples([(1,'a'),(1,'b'),(1,'c'),(2,'a')], names=['first','second']) df_mul Out[26]: one two three first second 1 a 2.0 9 NaN b 6.0 5 1.0 c 5.0 8 6.0 2 a NaN 6 1.0 df_mul.sub(col, axis=0, level='second') Out[29]: one two three first second 1 a -7.0 0.0 NaN b 1.0 0.0 -4.0 c -3.0 0.0 -2.0 2 a NaN -3.0 -8.0
對於缺失值在計算中的處理,fill_value引數可以為missing value指定替換值.
值得注意的是,只有在兩個相同shape的資料進行二元操作且相對應位置的元素不同時為缺失值時,fill_value引數才能使用
在存在廣播行為的計算中中,fill_value是無法使用的
df
Out[51]:
one two three
a 2.0 9 NaN
b 6.0 5 1.0
c 5.0 8 6.0
d NaN 6 1.0
df1
Out[49]:
one two three
a 2.0 9 9.0
b 6.0 5 1.0
c 5.0 8 6.0
d 9.0 6 1.0
df.sub(df1,fill_value=0)
Out[50]:
one two three
a 0.0 0 -9.0
b 0.0 0 0.0
c 0.0 0 0.0
d -9.0 0 0.0
靈活的比較操作
pandas中提供了eq,ne,lt,gt,le,ge 比較方法,操作方式與上面介紹的基本一致,只是,這些方法返回的都是與比較資料同shape的boolean型別的資料.
在比較重,NaN與任何值(包括標量和NaN)進行大小比較都是返回False,只有進行等於或不等於比較時才能根據實際情況返回(此情況需注意一點,np.nan 與 np.nan 相比永遠是返回False)
df
Out[77]:
one two three
a 2.0 9 10.0
b 6.0 5 1.0
c 5.0 8 6.0
d 10.0 6 1.0
df1
Out[78]:
one two three
a 2.0 9 9.0
b 6.0 5 1.0
c 5.0 8 6.0
d 9.0 6 1.0
df2
Out[79]:
one two three
a 2.0 9 NaN
b 6.0 5 1.0
c 5.0 8 6.0
d 9.0 6 1.0
df.gt(df1)
Out[80]:
one two three
a False False True
b False False False
c False False False
d True False False
df1.gt(df2)
Out[81]:
one two three
a False False False
b False False False
c False False False
d False False False
df.eq(df2)
Out[82]:
one two three
a True True False
b True True True
c True True True
d False True True
boolean值的推斷概要可以從empty
, any()
, all()
, and bool()
這幾個函式獲得.同樣可以控制軸方向
(df>5).any(0)
Out[88]:
one True
two True
three True
dtype: bool
(df>1).all(1)
Out[89]:
a True
b False
c True
d False
dtype: bool
上面的比較返回的是一組比較結果boolean值構成的資料集,要單獨比較兩個資料集是否相等(或者說一致),是需要另外一個方法的.
在pandas中,np.nan是不等於np.nan的
np.nan == np.nan
Out[91]: False
要比較兩個資料集是否一致,可以使用equals方法:
df.eq(df)
Out[93]:
one two three
a True True True
b True True True
c True True True
d True True True
df.equals(df)
Out[94]: True
(df+df).equals(df*2)
list-like物件的比較分為兩種
與標量比較是使用element-wise形式的,既自動廣播到所有元素
與list-like物件比較時,要求兩個比較的物件長度必須一致
pd.Series(['foo', 'bar', 'baz']) == 'foo'
Out[96]:
0 True
1 False
2 False
dtype: bool
pd.Series(['foo', 'bar', 'baz']) == np.array(['foo', 'bar', 'qux'])
Out[97]:
0 True
1 True
2 False
dtype: bool
pd.Series(['foo', 'bar', 'baz']) == pd.Series(['foo', 'bar'])
Traceback (most recent call last):
File "<ipython-input-98-93a189c0880c>", line 1, in <module>
pd.Series(['foo', 'bar', 'baz']) == pd.Series(['foo', 'bar'])
File "D:\Anaconda\lib\site-packages\pandas\core\ops.py", line 1190, in wrapper
raise ValueError("Can only compare identically-labeled "
ValueError: Can only compare identically-labeled Series objects
合併重疊資料
當兩個相似資料集進行重疊合並時,我們是希望將一個數據中的未知的缺失值替換為另一個數據中的已知的值.
這時可以使用combine_first方法
df
Out[135]:
one two three
a 2.0 9 10.0
b 6.0 100 1.0
c 5.0 8 100.0
d 10.0 6 1.0
df1
Out[136]:
one two three
a 2.0 9 NaN
b 6.0 5 NaN
c 5.0 8 NaN
d NaN 6 1.0
df1.combine_first(df)
Out[137]:
one two three
a 2.0 9 10.0
b 6.0 5 1.0
c 5.0 8 100.0
d 10.0 6 1.0
實質上,combine_first方法是呼叫的DataFrame的combine方法
該方法接收一個與要合併資料相同shape的Datafram和一個合併函式
combiner = lambda x, y: np.where(pd.isna(x), y, x)
df1.combine(df,combiner)
Out[139]:
one two three
a 2.0 9 10.0
b 6.0 5 1.0
c 5.0 8 100.0
d 10.0 6 1.0
三.描述性統計
pandas中提供許多的描述性統計需要的方法,有些返回聚合資料後的結構,如sum,mean等,有些返回一個和原資料相同shape的資料集,如:cumsum,cumprod等.同樣計算的方向可以由asix引數指定.
df.sum(1)
Out[141]:
a 21.0
b 107.0
c 113.0
d 17.0
dtype: float64
df.mean(0)
Out[142]:
one 5.75
two 30.75
three 28.00
dtype: float64
如果有缺失值,可以通過skipna引數指定是否忽略
df2.mean()
Out[144]:
one 5.500000
two 7.000000
three 2.666667
dtype: float64
df2.mean(skipna=False)
Out[145]:
one 5.5
two 7.0
three NaN
dtype: float64
使用describe方法可以快速資料統計的概要
df.describe()
Out[147]:
one two three
count 4.000000 4.000000 4.000000
mean 5.750000 30.750000 28.000000
std 3.304038 46.183511 48.187135
min 2.000000 6.000000 1.000000
25% 4.250000 7.500000 1.000000
50% 5.500000 8.500000 5.500000
75% 7.000000 31.750000 32.500000
max 10.000000 100.000000 100.000000
同時可以通過percentiles引數指定分位數
df.describe(percentiles=[.1,.7,.9])
Out[149]:
one two three
count 4.000000 4.000000 4.000000
mean 5.750000 30.750000 28.000000
std 3.304038 46.183511 48.187135
min 2.000000 6.000000 1.000000
10% 2.900000 6.600000 1.000000
50% 5.500000 8.500000 5.500000
70% 6.400000 18.100000 19.000000
90% 8.800000 72.700000 73.000000
max 10.000000 100.000000 100.000000
對應非數字型別的資料集,dexcribe返回的是對非數字元素的頻率統計,對應混合型資料集,dexcribe預設會提取其中的數字型別資料進行統計並只返回該結果
s = pd.Series(['a', 'a', 'b', 'b', 'a', 'a', np.nan, 'c', 'd', 'a'])
s.describe()
Out[154]:
count 9
unique 4
top a
freq 5
dtype: object
frame = pd.DataFrame({'a': ['Yes', 'Yes', 'No', 'No'], 'b': range(4)})
frame.describe()
Out[156]:
b
count 4.000000
mean 1.500000
std 1.290994
min 0.000000
25% 0.750000
50% 1.500000
75% 2.250000
max 3.000000
當然,對於混合型資料集的統計方式也是可以通過include引數指定的
frame.describe(include=['object'])
Out[104]:
a
count 4
unique 2
top Yes
freq 2
In [105]: frame.describe(include=['number'])
Out[105]:
b
count 4.000000
mean 1.500000
std 1.290994
min 0.000000
25% 0.750000
50% 1.500000
75% 2.250000
max 3.000000
In [106]: frame.describe(include='all')
Out[106]:
a b
count 4 4.000000
unique 2 NaN
top Yes NaN
freq 2 NaN
mean NaN 1.500000
std NaN 1.290994
min NaN 0.000000
25% NaN 0.750000
50% NaN 1.500000
75% NaN 2.250000
max NaN 3.000000
使用idxmax/idxmin查詢最大/最小值的索引值(Index):
s1 = pd.Series(np.random.randint(1,10,5))
s1
Out[172]:
0 9
1 1
2 3
3 1
4 4
dtype: int32
s1.idxmax()
Out[173]: 0
s1.idxmin()
Out[174]: 1
對於DataFrame來說同樣適用,適用axsi指定計算方向
df
Out[175]:
one two three
a 2.0 9 10.0
b 6.0 100 1.0
c 5.0 8 100.0
d 10.0 6 1.0
df.idxmax(0)
Out[176]:
one d
two b
three c
dtype: object
df.idxmax(1)
Out[177]:
a three
b two
c three
d one
dtype: object
元素計數統計value_counts僅適用於Series物件(DataFrame不適用)
pd.Series(random.choices(list('adcd'),k=20)).value_counts()
Out[186]:
d 9
a 6
c 5
dtype: int64
使用mode函式可以得到最高頻的元素(該方法適用DataFrame)
s = pd.Series([1, 1, 3, 3, 3, 3, 5, 7, 7, 7])
s.mode()
Out[189]:
0 3
dtype: int64
df5 = pd.DataFrame({"A": np.random.randint(0, 7, size=50),
.....: "B": np.random.randint(-10, 15, size=50)})
df5.mode()
Out[193]:
A B
0 2 -7
四.排序
支援三種方式的排序:
1.按照label排序(這個label'包含index和columns)
2.按照values排序(元素大小排序)
3.混合型(既按label又按照values)
第一種按照label排序的方式,label既可以是行的label(Index),也可以是列的label(columns),既可以升序也可以降序.
df = pd.DataFrame({'one' : pd.Series(np.random.randn(3), index=['a', 'b', 'c']),
.....: 'two' : pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
.....: 'three' : pd.Series(np.random.randn(3), index=['b', 'c', 'd'])})
.....:
In [308]: unsorted_df = df.reindex(index=['a', 'd', 'c', 'b'],
.....: columns=['three', 'two', 'one'])
.....:
In [309]: unsorted_df
Out[309]:
three two one
a NaN 0.708543 0.036274
d -0.540166 0.586626 NaN
c 0.410238 1.121731 1.044630
b -0.282532 -2.038777 -0.490032
# DataFrame
In [310]: unsorted_df.sort_index()
Out[310]:
three two one
a NaN 0.708543 0.036274
b -0.282532 -2.038777 -0.490032
c 0.410238 1.121731 1.044630
d -0.540166 0.586626 NaN
In [311]: unsorted_df.sort_index(ascending=False)
Out[311]:
three two one
d -0.540166 0.586626 NaN
c 0.410238 1.121731 1.044630
b -0.282532 -2.038777 -0.490032
a NaN 0.708543 0.036274
In [312]: unsorted_df.sort_index(axis=1)
Out[312]:
one three two
a 0.036274 NaN 0.708543
d NaN -0.540166 0.586626
c 1.044630 0.410238 1.121731
b -0.490032 -0.282532 -2.038777
# Series
In [313]: unsorted_df['three'].sort_index()
Out[313]:
a NaN
b -0.282532
c 0.410238
d -0.540166
Name: three, dtype: float64
第二種按values的順序來對整個資料集進行排序,如排序方向,升降序等引數基本與第一種方法類似
df1 = pd.DataFrame({'one':[2,1,1,1],'two':[1,3,2,4],'three':[5,4,3,2]})
df1.sort_values(by='two',axis=0)
Out[213]:
one two three
0 2 1 5
2 1 2 3
1 1 3 4
3 1 4 2
df1.sort_values(by=1,axis=1)
Out[214]:
one two three
0 2 1 5
1 1 3 4
2 1 2 3
3 1 4 2
df1.iloc[1,1]=np.nan
df1.sort_values(by='two',ascending=False,na_position='first')
Out[216]:
one two three
1 1 NaN 4
3 1 4.0 2
2 1 2.0 3
0 2 1.0 5
第三種同時按照行列label排序,一般是用在多層級的資料集中,注意的是如果行label和列label同名的話,列標籤優先.
idx = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('a', 2),
.....: ('b', 2), ('b', 1), ('b', 1)])
.....:
In [321]: idx.names = ['first', 'second']
# Build DataFrame
In [322]: df_multi = pd.DataFrame({'A': np.arange(6, 0, -1)},
.....: index=idx)
.....:
In [323]: df_multi
Out[323]:
A
first second
a 1 6
2 5
2 4
b 2 3
1 2
1 1
df_multi.sort_values(by=['second', 'A'])
Out[324]:
A
first second
b 1 1
1 2
a 1 6
b 2 3
a 2 4
2 5
最後介紹下去top值的問題,如果資料集很大的話,先對資料排序後再使用head或tail函式效率會非常低
這是可以使用nlargest或者nsmallest
s
Out[218]:
0 3
1 6
2 5
3 1
4 4
5 8
6 2
7 0
8 7
9 9
dtype: int32
s.nlargest(3)
Out[219]:
9 9
5 8
8 7
dtype: int32
s.nsmallest(3)
Out[220]:
7 0
3 1
6 2
dtype: int32
df = pd.DataFrame({'a': [-2, -1, 1, 10, 8, 11, -1],'b': list('abdceff'),'c': [1.0, 2.0, 4.0, 3.2, np.nan, 3.0, 4.0]})
df.nlargest(3,'a')
Out[226]:
a b c
5 11 f 3.0
3 10 c 3.2
4 8 e NaN
五.複製
pandas中的資料複製使用copy函式.
但大部分情況下,都不需要使用該函式.
這是因為pandas的資料的保護非常到位,也就是資料的不可觸碰原則(leaving the original object untouched)
只要不直接修改資料的自身屬性,其他的pandas提供的函式或者方法都不直接修改原資料,除非通過inplace引數指定
六.迭代
雖然pandas支援迴圈迭代,但從執行效率的角度並不建議,並且因為pandas的原資料不可觸碰性的原則,很多方法並不能對原資料集進行修改,而是返回新的物件或者檢視,所以有些迴圈迭代的修改資料並不一定能保證成功.
涉及到迴圈遍歷方面的操作,儘量採用向量化的操作方式或者使用函式應用的方式(函式應用方式後文會講)
首先,pandas中對不同型別資料的迴圈,得到的結果是不一樣的
對於Series物件,會像ndarray一樣得到的是每一個元素
s=pd.Series([1,2,3,'a','b'])
for i in s:
print(i)
1
2
3
a
b
對於DataFrame物件的迭代,返回的是其columns
df
Out[235]:
a b c
0 -2 a 1.0
1 -1 b 2.0
2 1 d 4.0
3 10 c 3.2
4 8 e NaN
5 11 f 3.0
6 -1 f 4.0
for i in df:
print(i)
a
b
c
為了便於對對資料的迭代,pandas中也提供了幾個方法:
iteritems:類似字典似的介面,返回的是(key,value)對
iterows:將每一行作為一個Series物件進行迭代
itertuples:將每一行資料作為namedtuple的資料格式進行返回
鑑於pandas中迴圈迭代的少用性,在此就略了,如有需要可以查閱官網.
七.重新索引和修改標籤
pandas最重要的特性就是資料的自動對齊,而reindex函式就是一個可以資料對齊的方法.reindex方法可以實現以下三個方面:
1.根據舊資料去匹配新的資料
2.在匹配不到資料的的位置填充缺失值
3.可以指定填充缺失資料的邏輯方法
s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
In [217]: s
Out[217]:
a -0.454087
b -0.360309
c -0.951631
d -0.535459
e 0.835231
dtype: float64
In [218]: s.reindex(['e', 'b', 'f', 'd'])
Out[218]:
e 0.835231
b -0.360309
f NaN
d -0.535459
dtype: float64
對DataFrame資料,可以同時重新索引行標籤和列標籤
df
Out[219]:
one two three
a -1.101558 1.124472 NaN
b -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
d NaN -0.456288 -1.222918
In [220]: df.reindex(index=['c', 'f', 'b'], columns=['three', 'two', 'one'])
Out[220]:
three two one
c 1.931194 -0.486066 0.462215
f NaN NaN NaN
b -0.634293 2.487104 -0.177289
df.reindex(['c', 'f', 'b'], axis='index')
Out[221]:
one two three
c 0.462215 -0.486066 1.931194
f NaN NaN NaN
b -0.177289 2.487104 -0.634293
Index或者columns物件是可以在資料集之間進行傳遞的
rs = s.reindex(df.index)
In [223]: rs
Out[223]:
a -0.454087
b -0.360309
c -0.951631
d -0.535459
dtype: float64
In [224]: rs.index is df.index
Out[224]: True
通過reindex_like方法,可以讓一個數據集根據另外一個數據集的index和columns來重新索引自身的index和columns
df2
Out[227]:
one two
a -1.101558 1.124472
b -0.177289 2.487104
c 0.462215 -0.486066
In [228]: df3
Out[228]:
one two
a -0.829347 0.082635
b 0.094922 1.445267
c 0.734426 -1.527903
In [229]: df.reindex_like(df2)
Out[229]:
one two
a -1.101558 1.124472
b -0.177289 2.487104
c 0.462215 -0.486066
對於reindex過程中產生的缺失值同樣可以設定填充方式和填充數量限制
rng = pd.date_range('1/3/2000', periods=8)
In [240]: ts = pd.Series(np.random.randn(8), index=rng)
In [241]: ts2 = ts[[0, 3, 6]]
In [242]: ts
Out[242]:
2000-01-03 0.466284
2000-01-04 -0.457411
2000-01-05 -0.364060
2000-01-06 0.785367
2000-01-07 -1.463093
2000-01-08 1.187315
2000-01-09 -0.493153
2000-01-10 -1.323445
Freq: D, dtype: float64
In [243]: ts2
Out[243]:
2000-01-03 0.466284
2000-01-06 0.785367
2000-01-09 -0.493153
dtype: float64
In [244]: ts2.reindex(ts.index)
Out[244]:
2000-01-03 0.466284
2000-01-04 NaN
2000-01-05 NaN
2000-01-06 0.785367
2000-01-07 NaN
2000-01-08 NaN
2000-01-09 -0.493153
2000-01-10 NaN
Freq: D, dtype: float64
In [245]: ts2.reindex(ts.index, method='ffill')
Out[245]:
2000-01-03 0.466284
2000-01-04 0.466284
2000-01-05 0.466284
2000-01-06 0.785367
2000-01-07 0.785367
2000-01-08 0.785367
2000-01-09 -0.493153
2000-01-10 -0.493153
Freq: D, dtype: float64
In [246]: ts2.reindex(ts.index, method='bfill')
Out[246]:
2000-01-03 0.466284
2000-01-04 0.785367
2000-01-05 0.785367
2000-01-06 0.785367
2000-01-07 -0.493153
2000-01-08 -0.493153
2000-01-09 -0.493153
2000-01-10 NaN
Freq: D, dtype: float64
In [247]: ts2.reindex(ts.index, method='nearest')
Out[247]:
2000-01-03 0.466284
2000-01-04 0.466284
2000-01-05 0.785367
2000-01-06 0.785367
2000-01-07 0.785367
2000-01-08 -0.493153
2000-01-09 -0.493153
2000-01-10 -0.493153
Freq: D, dtype: float64
ts2.reindex(ts.index, method='ffill', limit=1)
Out[249]:
2000-01-03 0.466284
2000-01-04 0.466284
2000-01-05 NaN
2000-01-06 0.785367
2000-01-07 0.785367
2000-01-08 NaN
2000-01-09 -0.493153
2000-01-10 -0.493153
Freq: D, dtype: float64
從資料集中刪除指定行標籤或者列標籤,使用drop函式即可
df
Out[251]:
one two three
a -1.101558 1.124472 NaN
b -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
d NaN -0.456288 -1.222918
In [252]: df.drop(['a', 'd'], axis=0)
Out[252]:
one two three
b -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
In [253]: df.drop(['one'], axis=1)
Out[253]:
two three
a 1.124472 NaN
b 2.487104 -0.634293
c -0.486066 1.931194
d -0.456288 -1.222918
重新命名行/列標籤的名稱,使用rename函式
df.rename(columns={'one': 'foo', 'two': 'bar'},
.....: index={'a': 'apple', 'b': 'banana', 'd': 'durian'})
.....:
Out[257]:
foo bar three
apple -1.101558 1.124472 NaN
banana -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
durian NaN -0.456288 -1.222918
df.rename({'one': 'foo', 'two': 'bar'}, axis='columns')
Out[258]:
foo bar three
a -1.101558 1.124472 NaN
b -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
d NaN -0.456288 -1.222918
In [259]: df.rename({'a': 'apple', 'b': 'banana', 'd': 'durian'}, axis='index')
Out[259]:
one two three
apple -1.101558 1.124472 NaN
banana -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
durian NaN -0.456288 -1.222918
八.函式應用
pandas提供了不同的方法可以對每個物件進行函式操作,而每個方法有不同的作用範圍:
1.pipe:表格級範圍
2.apply:行列級範圍
3.agg/transform:聚合的API介面(行列級範圍)
4.applyamp:元素級範圍
首先從表格級範圍的pipe說起.DtatFrame或者Series當然也可以作為引數傳遞給其他的函式,如果函式鏈式執行的話,那麼可以簡單為以下模式:
# f, g, and h are functions taking and returning ``DataFrames``
>>> f(g(h(df), arg1=1), arg2=2, arg3=3)
使用pipe的話,可以表述為如下模式:
(df.pipe(h)
.pipe(g, arg1=1)
.pipe(f, arg2=2, arg3=3)
)
行列級範圍函式
apply/agg(aggregate的別名)/transform三個方法都可以實現行/列範圍的函式運算.
DataFrame.
apply
(func, axis=0, raw=False,result_type=None, args=(), **kwds)
DataFrame.
agg
(func, axis=0, *args, **kwargs)
DataFrame.
transform
(func, *args, **kwargs).該方法不接受聚合型別的函式,如mean,sum.
df = pd.DataFrame(np.random.randint(1, 10,30).reshape(10,3), columns=['A', 'B', 'C'],index=pd.date_range('1/1/2000', periods=10))
以上三個方法中.func可以接受四種類型:
a.部分描述性統計方法的字元形式
df.apply('mean')
Out[20]:
A 4.3
B 6.6
C 5.0
dtype: float64
df.agg('mean')
Out[21]:
A 4.3
B 6.6
C 5.0
dtype: float64
df.transform('abs')
Out[26]:
A B C
2000-01-01 4 8 2
2000-01-02 7 1 5
2000-01-03 4 9 9
2000-01-04 7 5 8
2000-01-05 1 9 6
2000-01-06 6 2 3
2000-01-07 4 8 2
2000-01-08 2 8 7
2000-01-09 4 8 1
2000-01-10 4 8 7
b.函式名,包含自定義的
def add1(item):
return item+1
df.apply(func=add1)
Out[28]:
A B C
2000-01-01 5 9 3
2000-01-02 8 2 6
2000-01-03 5 10 10
2000-01-04 8 6 9
2000-01-05 2 10 7
2000-01-06 7 3 4
2000-01-07 5 9 3
2000-01-08 3 9 8
2000-01-09 5 9 2
2000-01-10 5 9 8
df.agg(func=add1)
Out[29]:
A B C
2000-01-01 5 9 3
2000-01-02 8 2 6
2000-01-03 5 10 10
2000-01-04 8 6 9
2000-01-05 2 10 7
2000-01-06 7 3 4
2000-01-07 5 9 3
2000-01-08 3 9 8
2000-01-09 5 9 2
2000-01-10 5 9 8
df.transform(func=add1)
Out[30]:
A B C
2000-01-01 5 9 3
2000-01-02 8 2 6
2000-01-03 5 10 10
2000-01-04 8 6 9
2000-01-05 2 10 7
2000-01-06 7 3 4
2000-01-07 5 9 3
2000-01-08 3 9 8
2000-01-09 5 9 2
2000-01-10 5 9 8
c.函式組成的列表
df.apply(['sum','min','max'])
Out[31]:
A B C
sum 43 66 50
min 1 1 1
max 7 9 9
df.agg(['sum','min','max'])
Out[32]:
A B C
sum 43 66 50
min 1 1 1
max 7 9 9
df.transform([abs,add1])
Out[33]:
A B C
abs add1 abs add1 abs add1
2000-01-01 4 5 8 9 2 3
2000-01-02 7 8 1 2 5 6
2000-01-03 4 5 9 10 9 10
2000-01-04 7 8 5 6 8 9
2000-01-05 1 2 9 10 6 7
2000-01-06 6 7 2 3 3 4
2000-01-07 4 5 8 9 2 3
2000-01-08 2 3 8 9 7 8
2000-01-09 4 5 8 9 1 2
2000-01-10 4 5 8 9 7 8
d.可以用字典方式指定列名和對應要執行的函式
df.apply({'A':sum,'B':max,'C':min})
Out[34]:
A 43
B 9
C 1
dtype: int64
df.agg({'A':sum,'B':max,'C':min})
Out[35]:
A 43
B 9
C 1
dtype: int64
df.transform({'A':abs,'C':add1})
Out[36]:
A C
2000-01-01 4 3
2000-01-02 7 6
2000-01-03 4 10
2000-01-04 7 9
2000-01-05 1 7
2000-01-06 6 4
2000-01-07 4 3
2000-01-08 2 8
2000-01-09 4 2
2000-01-10 4 8
至於apply方法中,其他引數可以查閱官網:
同時三個方法的差別,待後續研究明白再分析.
DataFrame元素級範圍的函式應用方法使用applymap,Series元素級範圍的函式應用方法使用map
In [188]: df4
Out[188]:
one two three
a -1.101558 1.124472 NaN
b -0.177289 2.487104 -0.634293
c 0.462215 -0.486066 1.931194
d NaN -0.456288 -1.222918
In [189]: f = lambda x: len(str(x))
In [190]: df4['one'].map(f)
Out[190]:
a 19
b 20
c 18
d 3
Name: one, dtype: int64
In [191]: df4.applymap(f)
Out[191]:
one two three
a 19 18 3
b 20 18 19
c 18 20 18
d 3 19 19
Series的map方法還有一個附件的功能,類似通過兩個有對應關係的Series建立新的Series
In [192]: s = pd.Series(['six', 'seven', 'six', 'seven', 'six'],
.....: index=['a', 'b', 'c', 'd', 'e'])
.....:
In [193]: t = pd.Series({'six' : 6., 'seven' : 7.})
In [194]: s
Out[194]:
a six
b seven
c six
d seven
e six
dtype: object
In [195]: s.map(t)
Out[195]:
a 6.0
b 7.0
c 6.0
d 7.0
e 6.0
dtype: float64
小結
本章介紹了一些pandas的基礎性功能,但僅涉及到Series和Dataframe.
因為Panel結構會在以後的Pandas版本中被棄用,所以本章中介紹的基本型功能都不涉及Panel結構.