本篇文章主要是針對pandas的基礎(chǔ)運用沿彭,做簡單的記錄匯總峻汉,加深印象互躬,以官方網(wǎng)站的api做練習(xí)开仰。
官方網(wǎng)址:http://pandas.pydata.org/pandas-docs/stable/10min.html
主要包括DataFrame拟枚、Series數(shù)據(jù)類型的切片取值、索引取值众弓、缺失值處理恩溅、篩選、更改值谓娃、填充脚乡、關(guān)聯(lián)边琉、合并伞梯、append、分組盒犹、以及stack捡遍、unstack锌订,和透視表用法,以及運算稽莉、畫圖、時間序列涩搓。污秆。這些用法算是pandas入門最基本的掌握,后面會繼續(xù)學(xué)習(xí)高級的pandas用法昧甘,因為pandas處理數(shù)據(jù)真的太強(qiáng)大了良拼,下次會舉些項目例子。
# 導(dǎo)入需要的包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# np.nan是數(shù)值型充边,pd.NaT是object類型
s = pd.Series([1,3,5,np.nan,6,8])
下面圖片可以看到具體生成s的數(shù)據(jù)類型
# 利用datetime數(shù)據(jù)格式做索引庸推,創(chuàng)建DataFrame。
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
# 利用dict數(shù)據(jù)對象創(chuàng)建DataFrame浇冰,注意pd.Timestamp和pd.Categorical這兩個對象
df2 = pd.DataFrame({ 'A' : 1.,
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' })
# 結(jié)果如下:
df2
Out[11]:
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
# 每一列的數(shù)據(jù)類型查看
df2.dtypes
Out[12]:
A float64
B datetime64[ns]
C float32
D int32
E category
F object(字符串是object型)
dtype: object
查看數(shù)據(jù)
# 默認(rèn)是前5行數(shù)據(jù)
df.head()
# 指定最后3行數(shù)據(jù)
df.tail(3)
# 查看索引
df.index
# 查看所有列名
df.columns
# 查看值
df.values
# 展示DataFrame的數(shù)據(jù)統(tǒng)計情況贬媒,包括計數(shù)、平均值肘习、最小值际乘、最大、標(biāo)準(zhǔn)差等數(shù)據(jù)指標(biāo)
df.describe()
# 數(shù)據(jù)轉(zhuǎn)置查看漂佩,也就是原來的列成為索引脖含,原來的索引成為列
df.T
# 根據(jù)某一軸罪塔,索引排序,下面選axis=1是根據(jù)列名排序养葵,ascending=False表示降序征堪,ascending=True表示升序
df.sort_index(axis=1, ascending=False)
# 根據(jù)某一列,值排序关拒,下面以列名B值進(jìn)行排序佃蚜,默認(rèn)是升序,從小到大
df.sort_values(by='B')
篩選數(shù)據(jù)
# 選擇某一列
df['A']
# 選擇某些行夏醉,比如下面選擇索引是0爽锥,1,2畔柔,也就是前三行氯夷,因為雖然索引是其他標(biāo)記別名,其實內(nèi)部還是以0,1,2,3……的索引靶擦,所以就可以根據(jù)0腮考,1,2等或者切片去選擇行
df[0:3]
# 同理玄捕,用已有的索引名獲取第2行踩蔚、第3行,第4行枚粘,發(fā)現(xiàn)了沒有馅闽,如果用默認(rèn)的0,1,2,3……,切片時不含尾標(biāo)的馍迄,但用已有的索引名福也,切片時含有尾標(biāo)。你可以打印查看
df['20130102':'20130104']
####
# 選擇某一行攀圈,如果你用df[0]就會報錯了暴凑,這個可不是選擇第一行啊。df.loc[0]也會報錯赘来,df.iloc[0]才是正確的现喳。后面介紹df.loc和df.iloc的區(qū)別
df.loc[dates[0]] # 正確,因為dates[0]是已定義的索引別名,而如果用df.loc[0]就錯誤犬辰,當(dāng)然df.iloc[0]這個是可以用默認(rèn)的0嗦篱,1,2等索引幌缝,是正確的默色。
df.iloc[0] # 正確,但df.iloc[dates[0]]就錯誤了,這個說明了df.iloc和df.loc的區(qū)別
# 行和列同時選
df.loc[:,['A','B']]
df.loc['20130102':'20130104',['A','B']]
df.loc[dates[0],'A'] 和 df.at[dates[0],'A'] 等同腿宰,只不過df.at更快的獲取該值,并且df.at不支持獲取多個值呕诉。
# 和前面介紹的一樣,df.loc和df.iloc的區(qū)別吃度,df.iloc只能用默認(rèn)的索引和列名甩挫,也就是0,1,2,3,4……
df.iloc[3:5,0:2]
df.iloc[[1,2,4],[0,2]]
df.iloc[1:3,:]
df.iloc[:,1:3]
df.iloc[1,1] 和 df.iat[1,1] 等同
#############################
# 根據(jù)布爾類型篩選數(shù)據(jù)
# 根據(jù)某列大于某值做判斷篩選,其實就是一列布爾類型值代入到DataFrame中篩選
df[df.A > 0]
Out[39]:
A B C D
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-04 0.721555 -0.706771 -1.039575 0.271860
# 根據(jù)DataFrame的值做判斷篩選椿每,這是滿足條件就篩選出來伊者,不滿足就會變?yōu)镹aN
df[df > 0]
Out[40]:
A B C D
2013-01-01 0.469112 NaN NaN NaN
2013-01-02 1.212112 NaN 0.119209 NaN
2013-01-03 NaN NaN NaN 1.071804
2013-01-04 0.721555 NaN NaN 0.271860
2013-01-05 NaN 0.567020 0.276232 NaN
2013-01-06 NaN 0.113648 NaN 0.524988
# 復(fù)制df
df2 = df.copy()
# 對df2新增一列
df2['E'] = ['one', 'one','two','three','four','three']
# 根據(jù)isin判斷做篩選,其實還是某一列的
df2[df2['E'].isin(['two','four'])]
更改值
s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102', periods=6))
# 下面就把列名F值去改變间护,賦值是Series數(shù)據(jù)
df['F'] = s1
# 同樣亦渗,把列名'D'去改變,賦值np.array數(shù)據(jù)
df.loc[:,'D'] = np.array([5] * len(df))
# 根據(jù)索引?列名去更改某一個值
df.at[dates[0],'A'] = 0
# 根據(jù)默認(rèn)索引?列名去更改某一值
df.iat[0,1] = 0
# 根據(jù)條件去更改值
df2 = df.copy()
df2[df2 > 0] = -df2
缺失數(shù)據(jù)
# 缺失數(shù)據(jù)一般用np.nan表示汁尺,默認(rèn)情況不會參與計算
# 改變df的索引法精,列名,生成新的DataFrame數(shù)據(jù)
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])
# 對0痴突,1行搂蜓,E列對應(yīng)的數(shù)據(jù)更改數(shù)據(jù)值
df1.loc[dates[0]:dates[1],'E'] = 1
df1
Out[57]:
A B C D F E
2013-01-01 0.000000 0.000000 -1.509059 5 NaN 1.0
2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
2013-01-03 -0.861849 -2.104569 -0.494929 5 2.0 NaN
2013-01-04 0.721555 -0.706771 -1.039575 5 3.0 NaN
# dropna函數(shù)功能:丟棄缺失值,參數(shù)how=‘a(chǎn)ny’只要任一行存在缺失值辽装,就丟棄帮碰。
df1.dropna(how='any')
Out[58]:
A B C D F E
2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
# fillna函數(shù)對缺失值填充
df1.fillna(value=5)
Out[59]:
A B C D F E
2013-01-01 0.000000 0.000000 -1.509059 5 5.0 1.0
2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
2013-01-03 -0.861849 -2.104569 -0.494929 5 2.0 5.0
2013-01-04 0.721555 -0.706771 -1.039575 5 3.0 5.0
# isna判斷缺失值
pd.isna(df1)
Out[60]:
A B C D F E
2013-01-01 False False False False True False
2013-01-02 False False False False False False
2013-01-03 False False False False False True
2013-01-04 False False False False False True
運算
# 列的平均值,如果是行的平均值拾积,參數(shù)axis=1即可殉挽,默認(rèn)是0
df.mean()
Out[61]:
A -0.004474
B -0.383981
C -0.687758
D 5.000000
F 3.000000
dtype: float64
# axis=1的情況
df.mean(1)
Out[62]:
2013-01-01 0.872735
2013-01-02 1.431621
2013-01-03 0.707731
2013-01-04 1.395042
2013-01-05 1.883656
2013-01-06 1.592306
Freq: D, dtype: float64
# 值推移
s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)
# 可以看到原2013-01-01、2013-01-02索引 對應(yīng)的值向下推移了2行拓巧,同時nan值補(bǔ)充上斯碌。
s
Out[64]:
2013-01-01 NaN
2013-01-02 NaN
2013-01-03 1.0
2013-01-04 3.0
2013-01-05 5.0
2013-01-06 NaN
Freq: D, dtype: float64
# DataFrame數(shù)據(jù)與Series數(shù)據(jù)做運算,用到廣播概念玲销,sub是相減
df.sub(s, axis='index')
apply函數(shù)
默認(rèn)在列上
df.apply(np.cumsum)
df.apply(lambda x: x.max() - x.min())
統(tǒng)計值出現(xiàn)的次數(shù)
s = pd.Series(np.random.randint(0, 7, size=10))
s
Out[69]:
0 4
1 2
2 1
3 2
4 6
5 4
6 4
7 6
8 4
9 4
dtype: int64
# 統(tǒng)計每個值出現(xiàn)的次數(shù)
s.value_counts()
Out[70]:
4 5
6 2
2 2
1 1
dtype: int64
字符串方法
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s.str.lower()
合并
# 相當(dāng)于sql語句中的union all
df = pd.DataFrame(np.random.randn(10, 4))
df
Out[74]:
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
# 先拆開输拇,再用concat合起來
pieces = [df[:3], df[3:7], df[7:]]
pd.concat(pieces)
Out[76]:
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
關(guān)聯(lián)
left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})
left
Out[79]:
key lval
0 foo 1
1 foo 2
#
right
Out[80]:
key rval
0 foo 4
1 foo 5
# 下面以列名key去關(guān)聯(lián)
pd.merge(left, right, on='key')
Out[81]:
key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5
#
left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})
#
left
Out[84]:
key lval
0 foo 1
1 bar 2
#
right
Out[85]:
key rval
0 foo 4
1 bar 5
# 主要和上面的那個例子作對比摘符,這個例子主要說明默認(rèn)連接是:內(nèi)連接
In [86]: pd.merge(left, right, on='key')
Out[86]:
key lval rval
0 foo 1 4
1 bar 2 5
append
df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
df
Out[88]:
A B C D
0 1.346061 1.511763 1.627081 -0.990582
1 -0.441652 1.211526 0.268520 0.024580
2 -1.577585 0.396823 -0.105381 -0.532532
3 1.453749 1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346 0.339969 -0.693205
5 -0.339355 0.593616 0.884345 1.591431
6 0.141809 0.220390 0.435589 0.192451
7 -0.096701 0.803351 1.715071 -0.708758
# 獲取第三行
s = df.iloc[3]
# 把s添加在df中贤斜,牛逼的pandas!
df.append(s, ignore_index=True)
Out[90]:
A B C D
0 1.346061 1.511763 1.627081 -0.990582
1 -0.441652 1.211526 0.268520 0.024580
2 -1.577585 0.396823 -0.105381 -0.532532
3 1.453749 1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346 0.339969 -0.693205
5 -0.339355 0.593616 0.884345 1.591431
6 0.141809 0.220390 0.435589 0.192451
7 -0.096701 0.803351 1.715071 -0.708758
8 1.453749 1.208843 -0.080952 -0.264610
分組
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C' : np.random.randn(8),
'D' : np.random.randn(8)})
# 以列A去分組逛裤,然后分組后求和瘩绒,看出默認(rèn)忽略了B列,因為B列是字符串類型带族,sum函數(shù)不支持
df.groupby('A').sum()
Out[93]:
C D
A
bar -2.802588 2.42611
foo 3.146492 -0.63958
# 同樣可以
df.groupby(['A','B']).sum()
下面的圖糾正一處錯誤锁荔,利用stack函數(shù),是把列名作為DataFrame的索引蝙砌,也就多加了一內(nèi)層索引阳堕,不是截圖說的作為某一列的值跋理。
stack用法
unstack用法
透視表
pivot_table用法
時間序列,這里不做詳解
時間序列
類別數(shù)據(jù)類型
df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
# 數(shù)據(jù)類型轉(zhuǎn)變?yōu)閏ategory數(shù)據(jù)類型恬总,并賦值給grade列前普,相當(dāng)于有3列名
# id,raw_grade,grade
df["grade"] = df["raw_grade"].astype("category")
df["grade"]
Out[129]:
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, dtype: category
Categories (3, object): [a, b, e]
# 更改之前的category數(shù)據(jù),用Series.cat.categories函數(shù)壹堰,之前是Categories (3, object): [a, b, e]拭卿,更改后變?yōu)閇"very good", "good", "very bad"],一一對應(yīng)
df["grade"].cat.categories = ["very good", "good", "very bad"]
# 利用set_categories設(shè)置類別有哪些贱纠,比如原來是 ["very good", "good", "very bad"]峻厚,也就3個類別,現(xiàn)在變?yōu)閇"very bad", "bad", "medium", "good", "very good"]谆焊,共5個類別惠桃。
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
#
df["grade"]
Out[132]:
0 very good
1 good
2 good
3 very good
4 very good
5 very bad
Name: grade, dtype: category
Categories (5, object): [very bad, bad, medium, good, very good]
df["grade"]
Out[132]:
0 very good
1 good
2 good
3 very good
4 very good
5 very bad
Name: grade, dtype: category
Categories (5, object): [very bad, bad, medium, good, very good]
# 根據(jù)值排序
df.sort_values(by="grade")
Out[133]:
id raw_grade grade
5 6 e very bad
1 2 b good
2 3 b good
0 1 a very good
3 4 a very good
4 5 a very good
畫圖
plot1
plot2
讀寫數(shù)據(jù),csv懊渡,hdf5刽射,Excel,數(shù)據(jù)庫等
# 寫入數(shù)據(jù)csv
df.to_csv('foo.csv')
# 讀取數(shù)據(jù)csv
pd.read_csv('foo.csv')
# 寫剃执、讀hdf5數(shù)據(jù)
df.to_hdf('foo.h5','df')
pd.read_hdf('foo.h5','df')
# 讀寫Excel
df.to_excel('foo.xlsx', sheet_name='Sheet1')
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])