貴有恒,何必三更起五更眠。最無(wú)益,只怕一日曝十日寒。 ——毛澤東
“手把手教你”系列將為Python初學(xué)者一一介紹Python在量化金融中運用最廣泛的幾個(gè)庫(Library): NumPy(數組、線(xiàn)性代數)、SciPy(統計)、pandas(時(shí)間序列、數據分析)、matplotlib(可視化分析)。建議安裝Anaconda軟件(自帶上述常見(jiàn)庫),并使用Jupyter Notebook交互學(xué)習。
對于Python零基礎的請關(guān)注公眾號CuteHand,并回復Python入門(mén),奉上Python的程序安裝和入門(mén)應用指南。對于Python的高階學(xué)習,如數據分析挖掘、機器學(xué)習和量化投資,請繼續關(guān)注公眾號的動(dòng)態(tài)。
Pandas的數據結構類(lèi)型:
Series (序列:一維列表)
DataFrame (數據框:二維表)
1. Series
定義:數據表中的一列或一行,觀(guān)測向量為一維數組,對于任意一組個(gè)體某一屬性的觀(guān)測可抽象為Series的概念。Series默認由index和values構成。
import pandas as pd
import numpy as np
1.1 Series的創(chuàng )建
創(chuàng )建Series 創(chuàng )建一個(gè)Series的基本格式是s = Series(data, index=index, name=name)
np.random.seed(1) #使用隨機種子,這樣每次運行random結果一致,
A=np.random.randn(5)
print('A is an array:\n',A)
S = pd.Series(a)
print('S is a Series:\n',S)
print('index: ', S.index) #默認創(chuàng )建索引,注意是從0開(kāi)始
print('values: ', S.values)
A is an array:
[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]
S is a Series:
0 1.624345
1 -0.611756
2 -0.528172
3 -1.072969
4 0.865408
dtype: float64
index: RangeIndex(start=0, stop=5, step=1)
values: [ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]
可以在創(chuàng )建Series時(shí)添加index,并可使用Series.index查看具體的index。需要注意的一點(diǎn)是,
當從數組創(chuàng )建Series時(shí),若指定index,那么index長(cháng)度要和data的
長(cháng)度一致
np.random.seed(2)
s=Series(np.random.randn(5),index=['a','b','c','d','e'])
print (s)
s.index
a -0.416758
b -0.056267
c -2.136196
d 1.640271
e -1.793436
dtype: float64
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
stocks={'中國平安':'601318','格力電器':'000651','招商銀行':'600036',
'中信證券':'600030','貴州茅臺':'600519'}
Series_stocks = Series(stocks)
print (s)
中國平安 601318
格力電器 000651
招商銀行 600036
中信證券 600030
貴州茅臺 600519
dtype: object
Series(stocks, index=['中國平安', '格力電器', '招商銀行', '中信證券',
'工業(yè)富聯(lián)'])
#注意,在原來(lái)的stocks(dict)里沒(méi)有‘工業(yè)富聯(lián)’,因此值為‘NaN’
中國平安 601318
格力電器 000651
招商銀行 600036
中信證券 600030
工業(yè)富聯(lián) NaN
dtype: object
Series_stocks.name='股票代碼' #注意python是使用.號來(lái)連接和調用
Series_stocks.index.name='股票名稱(chēng)'
print(Series_stocks)
股票名稱(chēng)
中國平安 601318
格力電器 000651
招商銀行 600036
中信證券 600030
貴州茅臺 600519
Name: 股票代碼, dtype: object
1.2 Series數據的訪(fǎng)問(wèn)
Series對象的下標運算同時(shí)支持位置和標簽兩種方式
np.random.seed(3)
data=np.random.randn(5)
s = Series(data,index=['a', 'b', 'c', 'd', 'e'])
s
a 1.624345
b -0.611756
c -0.528172
d -1.072969
e 0.865408
dtype: float64
s[:2] #取出第0、1行數據
a -0.670228
b 0.488043
dtype: float64
s[[2,0,4]] #取出第2、0、4行數據
c -0.528172
a 1.624345
e 0.865408
dtype: float64
s[['e', 'a']] #取出‘e’、‘a(chǎn)’對應數據
e 0.865408
a 1.624345
dtype: float64
1.3 Series排序函數
np.random.seed(3)
data=np.random.randn(10)
s = Series(data,index=['j','a', 'c','b', 'd', 'e','h','f','g','i'])
s
j 1.788628
a 0.436510
c 0.096497
b -1.863493
d -0.277388
e -0.354759
h -0.082741
f -0.627001
g -0.043818
i -0.477218
dtype: float64
#排序
s.sort_index(ascending=True) #按index從小到大,False從大到小
a 0.436510
b -1.863493
c 0.096497
d -0.277388
e -0.354759
f -0.627001
g -0.043818
h -0.082741
i -0.477218
j 1.788628
dtype: float64
s.sort_values(ascending=True)
b -1.863493
f -0.627001
i -0.477218
e -0.354759
d -0.277388
h -0.082741
g -0.043818
c 0.096497
a 0.436510
j 1.788628
dtype: float64
s.rank(method='average',ascending=True,axis=0) #每個(gè)數的平均排名
j 10.0
a 9.0
c 8.0
b 1.0
d 5.0
e 4.0
h 6.0
f 2.0
g 7.0
i 3.0
dtype: float64
#返回含有最大值的索引位置:
print(s.idxmax())
#返回含有最小值的索引位置:
print(s.idxmin())
j
b
根據索引返回已排序的新對象:
Series.sort_index(ascending=True)
根據值返回已排序的對象,NaN值在末尾:
Series.sort_values(ascending=True)
為各組分配一個(gè)平均排名:
Series.rank(method='average',ascending=True,axis=0)
rank的method選項:
'average':在相等分組中,為各個(gè)值分配平均排名
'max','min':使用整個(gè)分組中的最小排名
'first':按值在原始數據中出現的順序排名
返回含有最大值的索引位置:
Series.idxmax()
返回含有最小值的索引位置:
Series.idxmin()
2 Pandas數據結構:DataFrame
DataFrame是一個(gè)二維的數據結構,通過(guò)數據組,index和columns構成
2.1 DataFrame數據表的創(chuàng )建
DataFrame是多個(gè)Series的集合體。
先創(chuàng )建一個(gè)值是Series的字典,并轉換為DataFrame。
#通過(guò)字典創(chuàng )建DataFrame
d={'one':pd.Series([1.,2.,3.],index=['a','b','c']),
'two':pd.Series([1.,2.,3.,4.,],index=['a','b','c','d']),
'three':range(4),
'four':1.,
'five':'f'}
df=pd.DataFrame(d)
print (df)
one two three four five
a 1.0 1.0 0 1.0 f
b 2.0 2.0 1 1.0 f
c 3.0 3.0 2 1.0 f
d NaN 4.0 3 1.0 f
#可以使用dataframe.index和dataframe.columns來(lái)查看DataFrame的行和列,
#dataframe.values則以數組的形式返回DataFrame的元素
print ('DataFrame index:\n',df.index)
print ('DataFrame columns:\n',df.columns)
print ('DataFrame values:\n',df.values)
DataFrame index:
Index(['a', 'b', 'c', 'd'], dtype='object')
DataFrame columns:
Index(['one', 'two', 'three', 'four', 'five'], dtype='object')
DataFrame values:
[[1.0 1.0 0 1.0 'f']
[2.0 2.0 1 1.0 'f']
[3.0 3.0 2 1.0 'f']
[nan 4.0 3 1.0 'f']]
#DataFrame也可以從值是數組的字典創(chuàng )建,但是各個(gè)數組的長(cháng)度需要相同:
d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}
df = DataFrame(d, index=['a', 'b', 'c', 'd'])
print df
one two
a 1.0 4.0
b 2.0 3.0
c 3.0 2.0
d 4.0 1.0
#值非數組時(shí),沒(méi)有這一限制,并且缺失值補成NaN
d= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}]
df = DataFrame(d)
print df
a b c
0 1.6 2 NaN
1 3.0 6 9.0
#在實(shí)際處理數據時(shí),有時(shí)需要創(chuàng )建一個(gè)空的DataFrame,可以這么做
df = DataFrame()
print (df)
Empty DataFrame
Columns: []
Index: []
#另一種創(chuàng )建DataFrame的方法十分有用,那就是使用concat函數基于Series
#或者DataFrame創(chuàng )建一個(gè)DataFrame
a = Series(range(5)) #range(5)產(chǎn)生0到4
b = Series(np.linspace(4, 20, 5)) #linspace(a,b,c)
df = pd.concat([a, b], axis=1)
print (df)
0 1
0 0 4.0
1 1 8.0
2 2 12.0
3 3 16.0
4 4 20.0
其中的axis=1表示按列進(jìn)行合并,axis=0表示按行合并,
并且,Series都處理成一列,所以這里如果選axis=0的話(huà),
將得到一個(gè)10×1的DataFrame。下面這個(gè)例子展示了如何按行合并
DataFrame成一個(gè)大的DataFrame:
df = DataFrame()
index = ['alpha', 'beta', 'gamma', 'delta', 'eta']
for i in range(5):
a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]])
df = pd.concat([df, a], axis=0)
print (df)
0 1 2 3 4
alpha 0.0 0.0 0.0 0.0 0.0
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
eta 4.0 8.0 12.0 16.0 20.0
2.2 DataFrame數據的訪(fǎng)問(wèn)
#DataFrame是以列作為操作的基礎的,全部操作都想象成先從DataFrame里取一列,
#再從這個(gè)Series取元素即可。
#可以用datafrae.column_name選取列,也可以使用dataframe[]操作選取列
df = DataFrame()
index = ['alpha', 'beta', 'gamma', 'delta', 'eta']
for i in range(5):
a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]])
df = pd.concat([df, a], axis=0)
print('df: \n',df)
print ('df[1]:\n',df[1])
df.columns = ['a', 'b', 'c', 'd', 'e']
print('df: \n',df)
print ('df[b]:\n',df['b'])
print ('df.b:\n',df.b)
print ('df[['a','b']]:\n',df[['a', 'd']])
df:
0 1 2 3 4
alpha 0.0 0.0 0.0 0.0 0.0
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
eta 4.0 8.0 12.0 16.0 20.0
df[1]:
alpha 0.0
beta 2.0
gamma 4.0
delta 6.0
eta 8.0
Name: 1, dtype: float64
df:
a b c d e
alpha 0.0 0.0 0.0 0.0 0.0
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
eta 4.0 8.0 12.0 16.0 20.0
df[b]:
alpha 0.0
beta 2.0
gamma 4.0
delta 6.0
eta 8.0
Name: b, dtype: float64
df.b:
alpha 0.0
beta 2.0
gamma 4.0
delta 6.0
eta 8.0
Name: b, dtype: float64
df[['a','b']]:
a d
alpha 0.0 0.0
beta 1.0 4.0
gamma 2.0 8.0
delta 3.0 12.0
eta 4.0 16.0
#訪(fǎng)問(wèn)特定的元素可以如Series一樣使用下標或者是索引:
print (df['b'][2]) #第b列,第3行(從0開(kāi)始算)
print (df['b']['gamma']) #第b列,gamma對應行
4.0
4.0
##### df.loc['列或行名'],df.iloc[n]第n行,df.iloc[:,n]第n列
#若需要選取行,可以使用dataframe.iloc按下標選取,
#或者使用dataframe.loc按索引選取
print (df.iloc[1]) #選取第一行元素
print (df.loc['beta'])#選取beta對應行元素
a 1.0
b 2.0
c 3.0
d 4.0
e 5.0
Name: beta, dtype: float64
a 1.0
b 2.0
c 3.0
d 4.0
e 5.0
Name: beta, dtype: float64
#選取行還可以使用切片的方式或者是布爾類(lèi)型的向量:
print ('切片取數:\n',df[1:3])
bool_vec = [True, False, True, True, False]
print ('根據布爾類(lèi)型取值:\n',df[bool_vec]) #相當于選取第0、2、3行
切片取數:
a b c d e
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
根據布爾類(lèi)型取值:
a b c d e
alpha 0.0 0.0 0.0 0.0 0.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
#行列組合起來(lái)選取數據:
print (df[['b', 'd']].iloc[[1, 3]])
print (df.iloc[[1, 3]][['b', 'd']])
print (df[['b', 'd']].loc[['beta', 'delta']])
print (df.loc[['beta', 'delta']][['b', 'd']])
b d
beta 2.0 4.0
delta 6.0 12.0
b d
beta 2.0 4.0
delta 6.0 12.0
b d
beta 2.0 4.0
delta 6.0 12.0
b d
beta 2.0 4.0
delta 6.0 12.0
#如果不是需要訪(fǎng)問(wèn)特定行列,而只是某個(gè)特殊位置的元素的話(huà),
#dataframe.at和dataframe.iat
#是最快的方式,它們分別用于使用索引和下標進(jìn)行訪(fǎng)問(wèn)
print(df)
print (df.iat[2, 3]) #相當于第3行第4列
print (df.at['gamma', 'd'])
a b c d e
alpha 0.0 0.0 0.0 0.0 0.0
beta 1.0 2.0 3.0 4.0 5.0
gamma 2.0 4.0 6.0 8.0 10.0
delta 3.0 6.0 9.0 12.0 15.0
eta 4.0 8.0 12.0 16.0 20.0
8.0
8.0
2.3創(chuàng )建時(shí)間序列
pandas.date_range(start=None, end=None, periods=None, freq='D',
tz=None, normalize=False, name=None, closed=None, **kwargs)
dates=pd.date_range('20180101',periods=12,freq='m')
print (dates)
DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30',
'2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30',
'2018-10-31', '2018-11-30', '2018-12-31'], dtype='datetime64[ns]',
freq='M')
np.random.seed(5)
df=pd.DataFrame(np.random.randn(12,4),index=dates,
columns=list('ABCD'))
df
| A | B | C | D |
|---|
| 2018-01-31 | 0.441227 | -0.330870 | 2.430771 | -0.252092 |
|---|
| 2018-02-28 | 0.109610 | 1.582481 | -0.909232 | -0.591637 |
|---|
| 2018-03-31 | 0.187603 | -0.329870 | -1.192765 | -0.204877 |
|---|
| 2018-04-30 | -0.358829 | 0.603472 | -1.664789 | -0.700179 |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | -1.511180 | 0.644848 |
|---|
| 2018-06-30 | -0.980608 | -0.856853 | -0.871879 | -0.422508 |
|---|
| 2018-07-31 | 0.996440 | 0.712421 | 0.059144 | -0.363311 |
|---|
| 2018-08-31 | 0.003289 | -0.105930 | 0.793053 | -0.631572 |
|---|
| 2018-09-30 | -0.006195 | -0.101068 | -0.052308 | 0.249218 |
|---|
| 2018-10-31 | 0.197660 | 1.334849 | -0.086876 | 1.561532 |
|---|
| 2018-11-30 | -0.305853 | -0.477731 | 0.100738 | 0.355438 |
|---|
| 2018-12-31 | 0.269612 | 1.291963 | 1.139343 | 0.494440 |
|---|
#查看數據頭n行 ,默認n=5
df.head()
| A | B | C | D |
|---|
| 2018-01-31 | 0.441227 | -0.330870 | 2.430771 | -0.252092 |
|---|
| 2018-02-28 | 0.109610 | 1.582481 | -0.909232 | -0.591637 |
|---|
| 2018-03-31 | 0.187603 | -0.329870 | -1.192765 | -0.204877 |
|---|
| 2018-04-30 | -0.358829 | 0.603472 | -1.664789 | -0.700179 |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | -1.511180 | 0.644848 |
|---|
#查看數據最后3行
df.tail(3)
| A | B | C | D |
|---|
| 2018-10-31 | 0.197660 | 1.334849 | -0.086876 | 1.561532 |
|---|
| 2018-11-30 | -0.305853 | -0.477731 | 0.100738 | 0.355438 |
|---|
| 2018-12-31 | 0.269612 | 1.291963 | 1.139343 | 0.494440 |
|---|
#查看數據的index(索引),columns (列名)和數據
print(df.index)
DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30',
'2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30',
'2018-10-31', '2018-11-30', '2018-12-31'], dtype='datetime64[ns]',
freq='M')
print(df.columns)
Index(['A', 'B', 'C', 'D'], dtype='object')
print(df.values)
[[ 0.44122749 -0.33087015 2.43077119 -0.25209213]
[ 0.10960984 1.58248112 -0.9092324 -0.59163666]
[ 0.18760323 -0.32986996 -1.19276461 -0.20487651]
[-0.35882895 0.6034716 -1.66478853 -0.70017904]
[ 1.15139101 1.85733101 -1.51117956 0.64484751]
[-0.98060789 -0.85685315 -0.87187918 -0.42250793]
[ 0.99643983 0.71242127 0.05914424 -0.36331088]
[ 0.00328884 -0.10593044 0.79305332 -0.63157163]
[-0.00619491 -0.10106761 -0.05230815 0.24921766]
[ 0.19766009 1.33484857 -0.08687561 1.56153229]
[-0.30585302 -0.47773142 0.10073819 0.35543847]
[ 0.26961241 1.29196338 1.13934298 0.4944404 ]]
#數據轉置
# df.T
根據索引排序數據排序:(按行axis=0或列axis=1)
df.sort_index(axis=1,ascending=False)
| D | C | B | A |
|---|
| 2018-01-31 | -0.252092 | 2.430771 | -0.330870 | 0.441227 |
|---|
| 2018-02-28 | -0.591637 | -0.909232 | 1.582481 | 0.109610 |
|---|
| 2018-03-31 | -0.204877 | -1.192765 | -0.329870 | 0.187603 |
|---|
| 2018-04-30 | -0.700179 | -1.664789 | 0.603472 | -0.358829 |
|---|
| 2018-05-31 | 0.644848 | -1.511180 | 1.857331 | 1.151391 |
|---|
| 2018-06-30 | -0.422508 | -0.871879 | -0.856853 | -0.980608 |
|---|
| 2018-07-31 | -0.363311 | 0.059144 | 0.712421 | 0.996440 |
|---|
| 2018-08-31 | -0.631572 | 0.793053 | -0.105930 | 0.003289 |
|---|
| 2018-09-30 | 0.249218 | -0.052308 | -0.101068 | -0.006195 |
|---|
| 2018-10-31 | 1.561532 | -0.086876 | 1.334849 | 0.197660 |
|---|
| 2018-11-30 | 0.355438 | 0.100738 | -0.477731 | -0.305853 |
|---|
| 2018-12-31 | 0.494440 | 1.139343 | 1.291963 | 0.269612 |
|---|
#按某列的值排序
df.sort_values('A') #按A列的值從小到大排序
| A | B | C | D |
|---|
| 2018-06-30 | -0.980608 | -0.856853 | -0.871879 | -0.422508 |
|---|
| 2018-04-30 | -0.358829 | 0.603472 | -1.664789 | -0.700179 |
|---|
| 2018-11-30 | -0.305853 | -0.477731 | 0.100738 | 0.355438 |
|---|
| 2018-09-30 | -0.006195 | -0.101068 | -0.052308 | 0.249218 |
|---|
| 2018-08-31 | 0.003289 | -0.105930 | 0.793053 | -0.631572 |
|---|
| 2018-02-28 | 0.109610 | 1.582481 | -0.909232 | -0.591637 |
|---|
| 2018-03-31 | 0.187603 | -0.329870 | -1.192765 | -0.204877 |
|---|
| 2018-10-31 | 0.197660 | 1.334849 | -0.086876 | 1.561532 |
|---|
| 2018-12-31 | 0.269612 | 1.291963 | 1.139343 | 0.494440 |
|---|
| 2018-01-31 | 0.441227 | -0.330870 | 2.430771 | -0.252092 |
|---|
| 2018-07-31 | 0.996440 | 0.712421 | 0.059144 | -0.363311 |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | -1.511180 | 0.644848 |
|---|
#數據選取loc和iloc
df.loc[dates[0]]
A 0.441227
B -0.330870
C 2.430771
D -0.252092
Name: 2018-01-31 00:00:00, dtype: float64
df.loc['20180131':'20180430',['A','C']] #根據標簽取數
| A | C |
|---|
| 2018-01-31 | 0.441227 | 2.430771 |
|---|
| 2018-02-28 | 0.109610 | -0.909232 |
|---|
| 2018-03-31 | 0.187603 | -1.192765 |
|---|
| 2018-04-30 | -0.358829 | -1.664789 |
|---|
df.iloc[1:3,1:4] #根據所在位置取數,注意從0開(kāi)始數
| B | C | D |
|---|
| 2018-02-28 | 1.582481 | -0.909232 | -0.591637 |
|---|
| 2018-03-31 | -0.329870 | -1.192765 | -0.204877 |
|---|
df.iloc[[1,3,5],[0,3]] #根據特定行和列取數
| A | D |
|---|
| 2018-02-28 | 0.109610 | -0.591637 |
|---|
| 2018-04-30 | -0.358829 | -0.700179 |
|---|
| 2018-06-30 | -0.980608 | -0.422508 |
|---|
df[df.A>0] #相當于取出A列大于0時(shí)的數據列表
| A | B | C | D |
|---|
| 2018-01-31 | 0.441227 | -0.330870 | 2.430771 | -0.252092 |
|---|
| 2018-02-28 | 0.109610 | 1.582481 | -0.909232 | -0.591637 |
|---|
| 2018-03-31 | 0.187603 | -0.329870 | -1.192765 | -0.204877 |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | -1.511180 | 0.644848 |
|---|
| 2018-07-31 | 0.996440 | 0.712421 | 0.059144 | -0.363311 |
|---|
| 2018-08-31 | 0.003289 | -0.105930 | 0.793053 | -0.631572 |
|---|
| 2018-10-31 | 0.197660 | 1.334849 | -0.086876 | 1.561532 |
|---|
| 2018-12-31 | 0.269612 | 1.291963 | 1.139343 | 0.494440 |
|---|
df[df>0] #顯示值大于0的數,其余使用NaN代替
| A | B | C | D |
|---|
| 2018-01-31 | 0.441227 | NaN | 2.430771 | NaN |
|---|
| 2018-02-28 | 0.109610 | 1.582481 | NaN | NaN |
|---|
| 2018-03-31 | 0.187603 | NaN | NaN | NaN |
|---|
| 2018-04-30 | NaN | 0.603472 | NaN | NaN |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | NaN | 0.644848 |
|---|
| 2018-06-30 | NaN | NaN | NaN | NaN |
|---|
| 2018-07-31 | 0.996440 | 0.712421 | 0.059144 | NaN |
|---|
| 2018-08-31 | 0.003289 | NaN | 0.793053 | NaN |
|---|
| 2018-09-30 | NaN | NaN | NaN | 0.249218 |
|---|
| 2018-10-31 | 0.197660 | 1.334849 | NaN | 1.561532 |
|---|
| 2018-11-30 | NaN | NaN | 0.100738 | 0.355438 |
|---|
| 2018-12-31 | 0.269612 | 1.291963 | 1.139343 | 0.494440 |
|---|
數據篩選isin()
df2=df.copy() #復制df數據
df2['E']=np.arange(12)
df2
| A | B | C | D | E |
|---|
| 2018-01-31 | 0.441227 | -0.330870 | 2.430771 | -0.252092 | 0 |
|---|
| 2018-02-28 | 0.109610 | 1.582481 | -0.909232 | -0.591637 | 1 |
|---|
| 2018-03-31 | 0.187603 | -0.329870 | -1.192765 | -0.204877 | 2 |
|---|
| 2018-04-30 | -0.358829 | 0.603472 | -1.664789 | -0.700179 | 3 |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | -1.511180 | 0.644848 | 4 |
|---|
| 2018-06-30 | -0.980608 | -0.856853 | -0.871879 | -0.422508 | 5 |
|---|
| 2018-07-31 | 0.996440 | 0.712421 | 0.059144 | -0.363311 | 6 |
|---|
| 2018-08-31 | 0.003289 | -0.105930 | 0.793053 | -0.631572 | 7 |
|---|
| 2018-09-30 | -0.006195 | -0.101068 | -0.052308 | 0.249218 | 8 |
|---|
| 2018-10-31 | 0.197660 | 1.334849 | -0.086876 | 1.561532 | 9 |
|---|
| 2018-11-30 | -0.305853 | -0.477731 | 0.100738 | 0.355438 | 10 |
|---|
| 2018-12-31 | 0.269612 | 1.291963 | 1.139343 | 0.494440 | 11 |
|---|
df2[df2['E'].isin([0,2,4])]
| A | B | C | D | E |
|---|
| 2018-01-31 | 0.441227 | -0.330870 | 2.430771 | -0.252092 | 0 |
|---|
| 2018-03-31 | 0.187603 | -0.329870 | -1.192765 | -0.204877 | 2 |
|---|
| 2018-05-31 | 1.151391 | 1.857331 | -1.511180 | 0.644848 | 4 |
|---|
3. 缺失值處理
缺失值用NaN顯示
date3=pd.date_range('20181001',periods=5)
np.random.seed(6)
data=np.random.randn(5,4)
df3=pd.DataFrame(data,index=date3,columns=list('ABCD'))
df3
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 | 1.127064 | -1.514093 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 2.631281 | 0.601822 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 | 0.111128 | 0.129151 |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
df3.iat[3,3]=np.NaN #令第3行第3列的數為缺失值(0.129151)
df3.iat[1,2]=np.NaN #令第1行第2列的數為缺失值(1.127064)
df3
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 | NaN | -1.514093 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 2.631281 | 0.601822 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 | 0.111128 | NaN |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
#丟棄存在缺失值的行
#設定how=all只會(huì )刪除那些全是NaN的行:
df3.dropna(how='any')
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 2.631281 | 0.601822 |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
#刪除列也一樣,設置axis=1
df3.dropna(how='any',axis=1)
| A | B |
|---|
| 2018-10-01 | -0.311784 | 0.729004 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 |
|---|
| 2018-10-05 | 0.076128 | -0.155128 |
|---|
#thresh參數,如thresh=4,一行中至少有4個(gè)非NaN值,否則刪除
df3.iloc[2,2]=np.NaN
df3.dropna(thresh=4)
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
填充缺失值
fillna 還可以使用 method 參數
method 可以使用下面的方法
1 . pad/ffill:用前一個(gè)非缺失值去填充該缺失值
2 . backfill/bfill:用下一個(gè)非缺失值填充該缺失值
df3.fillna(method='ffill')
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 | 0.217821 | -1.514093 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 0.217821 | 0.601822 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 | 0.111128 | 0.601822 |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
df3.fillna(method='bfill')
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 | 0.111128 | -1.514093 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 0.111128 | 0.601822 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 | 0.111128 | 0.810655 |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
df3
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 | NaN | -1.514093 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 2.631281 | 0.601822 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 | 0.111128 | NaN |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
#使在改變DataFrame 和 Series 的操作時(shí),會(huì )返回一個(gè)新的對象,
#原對象不變,如果要改變原對象,可以添加參數 inplace = True用列均值填充
#使用該列的均值填充
df3['C'].fillna(df3['C'].mean(),inplace=True)
df3
| A | B | C | D |
|---|
| 2018-10-01 | -0.311784 | 0.729004 | 0.217821 | -0.899092 |
|---|
| 2018-10-02 | -2.486781 | 0.913252 | 0.898614 | -1.514093 |
|---|
| 2018-10-03 | 1.639291 | -0.429894 | 2.631281 | 0.601822 |
|---|
| 2018-10-04 | -0.335882 | 1.237738 | 0.111128 | NaN |
|---|
| 2018-10-05 | 0.076128 | -0.155128 | 0.634225 | 0.810655 |
|---|
4、統計
date4=pd.date_range('20181001',periods=5)
np.random.seed(7)
data4=np.random.randn(5,4)
df4=pd.DataFrame(data4,index=date3,columns=list('ABCD'))
df4
| A | B | C | D |
|---|
| 2018-10-01 | 1.690526 | -0.465937 | 0.032820 | 0.407516 |
|---|
| 2018-10-02 | -0.788923 | 0.002066 | -0.000890 | -1.754724 |
|---|
| 2018-10-03 | 1.017658 | 0.600499 | -0.625429 | -0.171548 |
|---|
| 2018-10-04 | 0.505299 | -0.261356 | -0.242749 | -1.453241 |
|---|
| 2018-10-05 | 0.554580 | 0.123881 | 0.274460 | -1.526525 |
|---|
描述性統計 df.describe()
df4.describe()
| A | B | C | D |
|---|
| count | 5.000000 | 5.000000 | 5.000000 | 5.000000 |
|---|
| mean | 0.595828 | -0.000170 | -0.112358 | -0.899704 |
|---|
| std | 0.908809 | 0.406618 | 0.340358 | 0.957784 |
|---|
| min | -0.788923 | -0.465937 | -0.625429 | -1.754724 |
|---|
| 25% | 0.505299 | -0.261356 | -0.242749 | -1.526525 |
|---|
| 50% | 0.554580 | 0.002066 | -0.000890 | -1.453241 |
|---|
| 75% | 1.017658 | 0.123881 | 0.032820 | -0.171548 |
|---|
| max | 1.690526 | 0.600499 | 0.274460 | 0.407516 |
|---|
df4.mean() #均值,默認按列axis=0
A 0.595828
B -0.000170
C -0.112358
D -0.899704
dtype: float64
df4.mean(axis=1) #按行
2018-10-01 0.416231
2018-10-02 -0.635618
2018-10-03 0.205295
2018-10-04 -0.363012
2018-10-05 -0.143401
Freq: D, dtype: float64
對數據使用函數df.apply()
df4.apply(np.cumsum) #np.cumsum()累加函數
| A | B | C | D |
|---|
| 2018-10-01 | 1.690526 | -0.465937 | 0.032820 | 0.407516 |
|---|
| 2018-10-02 | 0.901603 | -0.463872 | 0.031930 | -1.347208 |
|---|
| 2018-10-03 | 1.919261 | 0.136627 | -0.593499 | -1.518756 |
|---|
| 2018-10-04 | 2.424560 | -0.124730 | -0.836248 | -2.971998 |
|---|
| 2018-10-05 | 2.979140 | -0.000849 | -0.561788 | -4.498522 |
|---|
df4.apply(lambda x:x.max()-x.min()) #lambda自定義函數
#相當于計算每列里最大值-最小值
A 2.479449
B 1.066436
C 0.899889
D 2.162241
dtype: float64
df4['E']=['a','a','a','b','b']
df4
| A | B | C | D | E |
|---|
| 2018-10-01 | 1.690526 | -0.465937 | 0.032820 | 0.407516 | a |
|---|
| 2018-10-02 | -0.788923 | 0.002066 | -0.000890 | -1.754724 | a |
|---|
| 2018-10-03 | 1.017658 | 0.600499 | -0.625429 | -0.171548 | a |
|---|
| 2018-10-04 | 0.505299 | -0.261356 | -0.242749 | -1.453241 | b |
|---|
| 2018-10-05 | 0.554580 | 0.123881 | 0.274460 | -1.526525 | b |
|---|
#計算某個(gè)值出現評率
df4['E'].value_counts()
a 3
b 2
Name: E, dtype: int64
5、數據合并
#Concat()
d1=pd.Series(range(5))
print(d1)
d2=pd.Series(range(5,10))
print(d2)
0 0
1 1
2 2
3 3
4 4
dtype: int64
0 5
1 6
2 7
3 8
4 9
dtype: int64
pd.concat([d1,d2],axis=1) #默認是縱向合并即axis=0
#pd.merge(left_on=None, right_on=None, left_index=False,
#right_index=False)
d1=pd.DataFrame(np.random.randn(3,3),columns=list('ABC'))
print(d1)
d2=pd.DataFrame(np.random.randn(3,3),columns=list('DEF'))
print(d2)
pd.merge(d1,d2,left_index=True, right_index=True)
A B C
0 1.766161 -0.329414 0.840733
1 -0.179986 0.568062 -0.752837
2 -1.708339 -1.803099 0.383122
D E F
0 2.247595 0.269412 -0.524605
1 1.912019 0.237302 0.101434
2 0.252578 -0.132377 -0.309476
| A | B | C | D | E | F |
|---|
| 0 | 1.766161 | -0.329414 | 0.840733 | 2.247595 | 0.269412 | -0.524605 |
|---|
| 1 | -0.179986 | 0.568062 | -0.752837 | 1.912019 | 0.237302 | 0.101434 |
|---|
| 2 | -1.708339 | -1.803099 | 0.383122 | 0.252578 | -0.132377 | -0.309476 |
|---|
#增加1行數據:Append()
df = pd.DataFrame(np.random.randn(3, 3), columns=['A','B','C'])
df
| A | B | C |
|---|
| 0 | -0.923545 | -0.196027 | -0.590770 |
|---|
| 1 | -0.299711 | 1.296885 | 1.529580 |
|---|
| 2 | 0.669418 | 0.548745 | 0.676629 |
|---|
s=pd.Series([1.,1,1],index=list('ABC'))
df.append(s,ignore_index=True)
| A | B | C |
|---|
| 0 | -0.923545 | -0.196027 | -0.590770 |
|---|
| 1 | -0.299711 | 1.296885 | 1.529580 |
|---|
| 2 | 0.669418 | 0.548745 | 0.676629 |
|---|
| 3 | 1.000000 | 1.000000 | 1.000000 |
|---|
聚類(lèi)分析 groupby
df = pd.DataFrame({'A' : ['true', 'false', 'true', 'false',
'true', 'false', 'true', 'false'],
'B' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C' : np.random.randn(8),
'D' : np.random.randn(8)})
df
| A | B | C | D |
|---|
| 0 | true | one | -0.012242 | -0.864490 |
|---|
| 1 | false | one | -0.075663 | 0.374370 |
|---|
| 2 | true | two | -0.673645 | 0.391546 |
|---|
| 3 | false | three | -0.055867 | -1.443122 |
|---|
| 4 | true | two | 2.259947 | 0.486335 |
|---|
| 5 | false | two | 0.869039 | -0.569472 |
|---|
| 6 | true | one | -0.342117 | 1.426721 |
|---|
| 7 | false | three | -0.471927 | 0.156844 |
|---|
df.groupby(['A']).sum() #以A列特征分類(lèi)并加總
| C | D |
|---|
| A |
|
|
|---|
| false | 0.265582 | -1.481380 |
|---|
| true | 1.231943 | 1.440112 |
|---|
df.groupby(['A','B']).sum()
|
| C | D |
|---|
| A | B |
|
|
|---|
| false | one | -0.075663 | 0.374370 |
|---|
| three | -0.527794 | -1.286278 |
|---|
| two | 0.869039 | -0.569472 |
|---|
| true | one | -0.354359 | 0.562231 |
|---|
| two | 1.586302 | 0.877881 |
|---|
數據透視表
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
'B' : ['A', 'B', 'C'] * 4,
'C' : ['foo', 'foo', 'foo', 'bar', 'bar',
'bar'] * 2,
'D' : np.random.randn(12),
'E' : np.random.randn(12)})
df
| A | B | C | D | E |
|---|
| 0 | one | A | foo | 1.717730 | -0.390386 |
|---|
| 1 | one | B | foo | -0.458127 | -0.845923 |
|---|
| 2 | two | C | foo | -0.287984 | 0.637113 |
|---|
| 3 | three | A | bar | 0.299808 | 0.130623 |
|---|
| 4 | one | B | bar | 1.055948 | -0.075814 |
|---|
| 5 | one | C | bar | 0.565882 | 0.781302 |
|---|
| 6 | two | A | foo | -1.233524 | 0.488625 |
|---|
| 7 | three | B | foo | 0.182901 | 0.362190 |
|---|
| 8 | one | C | foo | 0.022245 | 0.964200 |
|---|
| 9 | one | A | bar | -0.429069 | 0.283636 |
|---|
| 10 | two | B | bar | -0.648105 | -0.616922 |
|---|
| 11 | three | C | bar | 1.747577 | -0.362282 |
|---|
pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
| C | bar | foo |
|---|
| A | B |
|
|
|---|
| one | A | -0.429069 | 1.717730 |
|---|
| B | 1.055948 | -0.458127 |
|---|
| C | 0.565882 | 0.022245 |
|---|
| three | A | 0.299808 | NaN |
|---|
| B | NaN | 0.182901 |
|---|
| C | 1.747577 | NaN |
|---|
| two | A | NaN | -1.233524 |
|---|
| B | -0.648105 | NaN |
|---|
| C | NaN | -0.287984 |
|---|
6、數據可視化(畫(huà)圖)
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 用來(lái)正常顯示中文標簽
mpl.rcParams['axes.unicode_minus']=False # 用來(lái)正常顯示負號
%matplotlib inline
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000',
periods=1000))
ts = ts.cumsum()
ts.plot(figsize=(12,8))
#利用tushare包抓取股票數據并畫(huà)圖
#得到的是DataFrame的數據結構
import tushare as ts
df=ts.get_k_data('sh',start='1990-01-01')
import pandas as pd
df.index=pd.to_datetime(df['date'])
df['close'].plot(figsize=(12,8))
plt.title('上證指數走勢')