閱讀提示
本文將提到:Pandas的初識、基本操作、Series和DataFrame簡介、簡單操作、pandas對日期的簡單處理等內容
目錄
引言
對於數據科學家,無論是數據分析還是數據挖掘來說,Pandas是一個非常重要的Python包。它不僅提供了很多方法,使得數據處理非常簡單,同時在數據處理速度上也做了很多優化,使得和Python內置方法相比時有了很大的優勢。
如果你想學習Pandas,建議先看兩個網站。
-
十分鐘入門Pandas:10 Minutes to pandas
在第一次學習Pandas的過程中,你會發現你需要記憶很多的函數和方法。所以在這裏彙總一下Pandas官方文檔 中比較常用的函數和方法,以方便大家記憶。
關鍵縮寫和包導入
在這個速查手冊中,我們使用如下縮寫:
df:任意的Pandas DataFrame對象
同時我們需要做如下的引入:
import pandas as pd
導入數據
pd.read_csv(filename):從CSV文件導入數據
pd.read_table(filename):從限定分隔符的文本文件導入數據
pd.read_excel(filename):從Excel文件導入數據
pd.read_sql(query, connection_object):從SQL表/庫導入數據
pd.read_json(json_string):從JSON格式的字符串導入數據
pd.read_html(url):解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_clipboard():從你的粘貼板獲取內容,並傳給read_table()
pd.DataFrame(dict):從字典對象導入數據,Key是列名,Value是數據
導出數據
df.to_csv(filename):導出數據到CSV文件
df.to_excel(filename):導出數據到Excel文件
df.to_sql(table_name, connection_object):導出數據到SQL表
df.to_json(filename):以Json格式導出數據到文本文件
創建測試對象
pd.DataFrame(np.random.rand(20,5)):創建20行5列的隨機數組成的DataFrame對象
pd.Series(my_list):從可迭代對象my_list創建一個Series對象
df.index = pd.date_range('1900/1/30', periods=df.shape[0]):增加一個日期索引
查看、檢查數據
df.head(n):查看DataFrame對象的前n行
df.tail(n):查看DataFrame對象的最後n行
df.shape():查看行數和列數
df.info():查看索引、數據類型和內存信息
df.describe():查看數值型列的彙總統計
s.value_counts(dropna=False):查看Series對象的唯一值和計數
df.apply(pd.Series.value_counts):查看DataFrame對象中每一列的唯一值和計數
數據選取
df[col]:根據列名,並以Series的形式返回列
df[[col1, col2]]:以DataFrame形式返回多列
s.iloc[0]:按位置選取數據
s.loc['index_one']:按索引選取數據
df.iloc[0,:]:返回第一行
df.iloc[0,0]:返回第一列的第一個元素
數據清理
df.columns = ['a','b','c']:重命名列名
pd.isnull():檢查DataFrame對象中的空值,並返回一個Boolean數組
pd.notnull():檢查DataFrame對象中的非空值,並返回一個Boolean數組
df.dropna():刪除所有包含空值的行
df.dropna(axis=1):刪除所有包含空值的列
df.dropna(axis=1,thresh=n):刪除所有小於n個非空值的行
df.fillna(x):用x替換DataFrame對象中所有的空值
s.astype(float):將Series中的數據類型更改爲float類型
s.replace(1,'one'):用‘one’代替所有等於1的值
s.replace([1,3],['one','three']):用'one'代替1,用'three'代替3
df.rename(columns=lambda x: x + 1):批量更改列名
df.rename(columns={'old_name': 'new_ name'}):選擇性更改列名
df.set_index('column_one'):更改索引列
df.rename(index=lambda x: x + 1):批量重命名索引
數據處理:Filter、Sort和GroupBy
df[df[col] > 0.5]:選擇col列的值大於0.5的行
df.sort_values(col1):按照列col1排序數據,默認升序排列
df.sort_values(col2, ascending=False):按照列col1降序排列數據
df.sort_values([col1,col2], ascending=[True,False]):先按列col1升序排列,後按col2降序排列數據
df.groupby(col):返回一個按列col進行分組的Groupby對象
df.groupby([col1,col2]):返回一個按多列進行分組的Groupby對象
df.groupby(col1)[col2]:返回按列col1進行分組後,列col2的均值
df.pivot_table(index=col1, values=[col2,col3], aggfunc=max):創建一個按列col1進行分組,並計算col2和col3的最大值的數據透視表
df.groupby(col1).agg(np.mean):返回按列col1分組的所有列的均值
data.apply(np.mean):對DataFrame中的每一列應用函數np.mean
data.apply(np.max,axis=1):對DataFrame中的每一行應用函數np.max
數據合併
df1.append(df2):將df2中的行添加到df1的尾部
df.concat([df1, df2],axis=1):將df2中的列添加到df1的尾部
df1.join(df2,on=col1,how='inner'):對df1的列和df2的列執行SQL形式的join
數據統計
df.describe():查看數據值列的彙總統計
df.mean():返回所有列的均值
df.corr():返回列與列之間的相關係數
df.count():返回每一列中的非空值的個數
df.max():返回每一列的最大值
df.min():返回每一列的最小值
df.median():返回每一列的中位數
df.std():返回每一列的標準差
一、Series和DataFrame介紹
1、什麼是pandas
pandas 是基於 NumPy 的一個 Python 數據分析包,主要目的是爲了數據分析。它提供了大量高級的數據結構和對數據處理的方法。
pandas 有兩個主要的數據結構:Series 和 DataFrame。
2、Series
Series 是一個一維數組對象 ,類似於 NumPy 的一維 array。它除了包含一組數據還包含一組索引,所以可以把它理解爲一組帶索引的數組。
eg_創建Series對象
#1.將數組轉化爲Series對象
#當沒有指定索引時,Series自動從0開始,步長爲1創建索引。可以加index參數爲其添加索引
Series1 = Series([1,2,3,4,5])
Series1 = Series([1,2,3,4,5], index = ['a','b','c','d','e'])
'''
結果:
0 1
1 2
2 3
3 4
4 5
dtype: int64
'''
#2.將字典轉化爲Series對象
dic = {'yang':1}
Series2 = Series(dic)
'''
結果:
yang 1
dtype: int64
'''
3、DataFrame
DataFrame是一個表格型的數據結構,它提供有序列和不同類型的列值
eg_創建DataFrame對象
#1、dataframe對象
data = {'name':['jack','tom','marry'],'age':[20,19,30],'gender':['m','m','w']}
frame = DataFrame(data)
'''
frame:
name age gender
0 jack 20 m
1 tom 19 m
2 marry 30 w
'''
#2、DataFrame 默認根據列名首字母順序進行排序,想要指定列的順序?傳入一個列名的字典即可:
frame = DataFrame(data, columns = ['name','gender','age'])
'''
frame:
name gender age
0 jack m 20
1 tom m 19
2 marry w 30
'''
#3、如果傳入的列名不存在,不會報錯,但會產生一個NaN值(not a number)
frame = DataFrame(data, columns = ['name','gender','age','weight'])
'''
frame
name gender age weight
0 jack m 20 NaN
1 tom m 19 NaN
2 marry w 30 NaN
'''
'''
4、DataFrame不光可以通過字典索引的方式獲取數據,還可以使用屬性的方法:
frame['name'] <==> frame.name
結果:
0 jack
1 tom
2 marry
Name: name, dtype: object
'''
二、Series和DataFrame的簡單操作
1、創建
由numpy創建的
#由 numpy創建的 帶有索引的
s1 = Series(data = np.random.randint(0,150,size = 5),index = ['python','h5','java','go','r'],name = "name")
#結果:
python 40
h5 46
java 52
go 20
r 78
Name: name, dtype: int32
#如果不指定索引,自動生成默認索引
s2 = Series(data = np.random.randint(0,150,size = 5))
#結果
0 60
1 42
2 135
3 127
4 51
dtype: int32
由列表創建的
l1 = [10,20,19,32,56]
s3 = Series(l1,index = list('abcde'))
#結果
a 10
b 20
c 19
d 32
e 35
dtype: int64
由字典創建的
s4 = Series({"Nobel" : 200, "GaoYang" : 900}, name = 'sorce')
#結果
Nobel 200
GaoYang 900
Name: score, dtype: object
2、reindex()方法:重建索引
針對Series
'''
重建索引指的是根據index參數重新進行排序。
如果傳入的索引值在數據裏不存在,則不會報錯,而是添加缺失值的新行。
不想用缺失值,可以用 fill_value 參數指定填充值。
'''
c1 = Series([1,2,3],index = ['a','c','b'])
'''
c1
a 1
c 2
b 3
dtype: int64
'''
c2 = c1.reindex(['b','a','c'])
'''
c2
b 3
a 1
c 2
dtype: int64
'''
c3 = c2.reindex(['c','b','a','d'])
'''
c3
c 2.0
b 3.0
a 1.0
d NaN
dtype: float64
'''
c4 = c2.reindex(['c','b','a','d'],fill_value = 0)
'''
c4
c 2
b 3
a 1
d 0
dtype: int64
'''
#fill_value 會讓所有的缺失值都填充爲同一個值,如果不想這樣而是用相鄰的元素(左或者右)的值填充,則可以用參數 ffill 和 bfill,分別爲用前值填充和用後值填充
c5 = c2.reindex(['c','b','a','d']).ffill()
c6 = c2.reindex(['c','b','a','d']).bfill()
針對DataFrame
#重建索引
frame = DataFrame(np.arange(9).reshape((3,3)),index = ['a','b','c'],columns = ['aa','bb','cc'])
'''
frame
aa bb cc
a 0 1 2
b 3 4 5
c 6 7 8
'''
frame2 = frame.reindex(['a','b','c','d'])
'''
frame2 變爲浮點數的原因是 NaN是float類型
aa bb cc
a 0.0 1.0 2.0
b 3.0 4.0 5.0
c 6.0 7.0 8.0
d NaN NaN NaN
'''
frame3 = frame.reindex(columns = ['aa','bb','cc','dd'])
'''
frame3
aa bb cc dd
a 0 1 2 NaN
b 3 4 5 NaN
c 6 7 8 NaN
'''
frame4 =frame.reindex(index = ['a','b','c','d'],columns=['aa','bb','cc']).ffill()
'''
frame4
aa bb cc
a 0.0 1.0 2.0
b 3.0 4.0 5.0
c 6.0 7.0 8.0
d 6.0 7.0 8.0
'''
3、drop()方法
針對Series
#只能對行進行刪除
data = DataFrame(np.arange(16).reshape((4,4)),index = list([1,2,3,4]),columns = ['jack','tony','lucy','herry'])
'''
data
jack tony lucy herry
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data.drop([1])
'''
結果
jack tony lucy herry
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
針對DataFrame
#不光可以刪除行,還可以刪除列
data = DataFrame(np.arange(16).reshape((4,4)),index = list([1,2,3,4]),columns = ['jack','tony','lucy','herry'])
'''
data
jack tony lucy herry
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data.drop['1']
'''
結果
jack tony lucy herry
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data.drop('jack',axis = 1) #axis=1 時候刪除列元素
'''
結果
tony lucy herry
1 1 2 3
2 5 6 7
3 9 10 11
4 13 14 15
'''
4、索引、選取和過濾
- 顯式索引
- 使用index中的元素作爲索引值(比如字符串)
- 使用
.loc[]
(全閉區間 --> 左右都包含)
- 隱式索引
- 使用整數作爲索引值
- 使用
.loc[]
(左閉右開)
1、顯式索引
s3 = Series(l,index = list('abcde'))
'''s3:
a 10
b 20
c 19
d 32
e 35
dtype: int64
s3['b'] <==> s3.loc['b'] --> 20
s3['a':'d'] <==> s3.loc['a':'d']
'''
2、隱式索引
'''
s3[2] = s3.iloc[2] --> 19
s3.iloc[0:2] --> a 10
b 20
dtype: int64
'''
針對Series
① 索引、切片
object = Series(np.arange(4.),index = ['a','b','c','d'])
'''
object
a 0.0
b 1.0
c 2.0
d 3.0
dtype: float64
object['b'] <==> object[1] = 1.0
object[['a','b']] <==> a 0.0
b 1.0
dtype: float64
object[2:4] <==> c 2.0
d 3.0
dtype: float64
object['a':'c'] <==> a 0.0
b 1.0
c 2.0
dtype: float64
'''
注:
利用索引的切片運算與普通的 Python 切片運算不同,其末端是包含的,既包含最後一個的項。
② 賦值
object['a','b'] = 100
'''
obj
a 100.0
b 100.0
c 2.0
d 3.0
dtype: float64
'''
針對DataFrame
① 索引和切片
'''
data
jack tony lucy herry
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data['jack']
data[['jack','tony']]
data[:2] # 注 這裏是左閉右開的
5、算數運算和數據對齊
針對Series
#將兩個對象相加的時候,具有相同索引的值會相加,不重疊的則會區並集,值爲NaN
s1 = Series([1,2,3,4],index = ['a','b','c','d'])
'''
s1
a 1
b 2
c 3
d 4
dtype: int64
'''
s2 = Series([10,20,30,40],index = ['x','b','c','y'])
'''
s2
x 10
b 20
c 30
y 40
dtype: int64
'''
s1 + s2
'''
結果:
a NaN
b 22.0
c 33.0
d NaN
x NaN
y NaN
dtype: float64
'''
針對DataFrame
#對齊操作會同時發生在行和列上,把2個對象相加會得到一個新的對象,其索引爲原來2個對象的索引的並集
df1 = DataFrame(np.arange(9.).reshape((3,3)), columns = list('abc'),index = ['beijing','shanghai','guangzhou'])
'''
df1
a b c
beijing 0.0 1.0 2.0
shanghai 3.0 4.0 5.0
guangzhou 6.0 7.0 8.0
'''
df2 = DataFrame(np.arange(12.).reshape((4,3)),columns = list('cde'),index = ['beijing','guangzhou','Tees','newyork'])
'''
df2
c d e
beijing 0.0 1.0 2.0
guangzhou 3.0 4.0 5.0
Tees 6.0 7.0 8.0
newyork 9.0 10.011.0
'''
df1 + df2
'''
結果
a b c d e
Tees NaN NaN NaN NaN NaN
beijing NaN NaN 2.0 NaN NaN
guangzhou NaN NaN 11.0NaN NaN
newyork NaN NaN NaN NaN NaN
shanghai NaN NaN NaN NaN NaN
'''
注:與Series對象一樣,不重疊的索引會取並集,值爲NaN,如果不想這樣,可以通過add()方法進行數據填充
df1 = DataFrame(np.arange(9.).reshape((3,3)),columns = list('abc'), index = ['a1','b1','c1'])
'''
df1
a b c
a1 0.0 1.0 2.0
b1 3.0 4.0 5.0
c1 6.0 7.0 8.0
'''
df2 = DataFrame(np.arange(16.).reshape((4,4)),columns = list('abcd'),index = ['a1','b1','c1','d1'])
'''
df2
a b c d
a1 0.0 1.0 2.0 3.0
b1 4.0 5.0 6.0 7.0
c1 8.0 9.0 10.0 11.0
d1 12.0 13.0 14.0 15.0
'''
df1 + df2
'''
結果
a b c d
a1 0.0 2.0 4.0 NaN
b1 7.0 9.0 11.0 NaN
c1 14.0 16.0 18.0 NaN
d1 NaN NaN NaN NaN
'''
#通過add()來避免產生NaN值
df1.add(df2,fill_value = 0) #將空的地方先用0代替 然後再進行相加減
'''
結果
a b c d
a1 0.0 2.0 4.0 3.0
b1 7.0 9.0 11.0 7.0
c1 14.0 16.0 18.0 11.0
d1 12.0 13.0 14.0 15.0
'''
6、函數應用和映射
將一個lambda表達式應用到每列數據裏
df2 = df1.astype(np.int32) #as type 修改類型
'''
df2
a b c
a1 0 1 2
b1 3 4 5
c1 6 7 8
'''
f = lambda x: x + 1
df2.apply(f) #每列數據都+1
'''結果
a b c
a1 1 2 3
b1 4 5 6
c1 7 8 9
'''
f2 = lambda x: x.max() - x.min()
f3 = lambda x: x.mean() - x.min()
df2.apply(f2)
'''結果
a 6
b 6
c 6
dtype: int64
'''
除了lambda表達式還可以定義一個函數:
def f4(x):
return Series([x.min(),x.max()],index=['min','max'])
df2.apply(f4)
'''結果
a b c
min 0 1 2
max 6 7 8
'''
7、排序
針對Series
s1 = Series(range(4),index = ['b','d','a','c'])
s1.sort_index()
'''結果
a 2
b 0
c 3
d 1
dtype: int64
'''
s2 = Series(list([1,4,9,2]),index=['b','d','a','c'])
s2.sort_values() #默認是升序排列 若想爲降序則s2.sort(ascending = False)
'''結果
b 1
c 2
d 4
a 9
dtype: int64
'''
針對DataFrame
frame = DataFrame(np.arange(8).reshape((2,4)),index = ['two','one'],columns = ['a','d','c','b'])
'''
frame
a d c b
two 0 1 2 3
one 4 5 6 7
'''
frame.sort_index()
'''
這樣排序的是行的索引
a d c b
one 4 5 6 7
two 0 1 2 3
'''
frame.sort_index(axis=1)
'''
這樣排序的是列的索引
a b c d
two 0 3 2 1
one 4 7 6 5
'''
8、排名
obj = Series([100,80,99,54,86,12])
obj.rank()
'''
obj
0 100
1 80
2 99
3 54
4 86
5 12
dtype: int64
按從小到大排序(也就是說100是最小的)
0 6.0
1 3.0
2 5.0
3 2.0
4 4.0
5 1.0
dtype: float64
'''
obj.rank(ascending = False)
'''
按從大到小排序
0 1.0
1 4.0
2 2.0
3 5.0
4 3.0
5 6.0
dtype: float64
'''
9、帶有重複值的軸索引
索引是不強制唯一的
obj = Series(range(5),index = ['a','a','c','d','d'])
'''
obj
a 0
a 1
c 2
d 3
d 4
dtype: int64
'''
obj.index.is_unique
#返回false
obj.a
'''
結果
a 0
a 1
dtype: int64
'''
三、pandas日期數據處理
- 按日期篩選數據
- 按日期顯示數據
- 按日期統計數據
1、讀取數據
df = pd.read_csv('date.csv', header=None)
2、整理數據
df.columns = ['date','number'] #重新排列csv文件中的列順序
df['date'] = pd.to_datetime(df['date']) #將數據類型轉換爲日期類型
df = df.set_index('date') # 將date設置爲index
3、構造Series類型數據
s = pd.Series(df['number'], index=df.index)
4、按日期進行篩選
#獲取某幾天的數據
df['2020-1-20':'2020-1-30'].head(10)
# 獲取具體某天的數據,用datafrme直接選取某天時會報錯,而series的數據就沒有問題
df['2013-11-06']
5、turncate函數
# dataframe的truncate函數可以獲取某個時期之前或之後的數據,或者某個時間區間的數據
# 但一般建議直接用切片(slice),這樣更爲直觀,方便
#某個日期之前
print(df.truncate(after = '2013-11'))
#某個日期之後
print(df.truncate(before='2017-02'))
6、按日期顯示數據
'''
請注意df.index的數據類型是DatetimeIndex;
df_peirod的數據類型是PeriodIndex
'''
###1、to_period()方法
#按月顯示
df_period = df.to_period('M') #按月顯示,但不統計 (效果就是隻顯示xx年xx月 不顯示日)
print(type(df_period))
#按季度顯示
print(df.to_period('Q').head()) #按季度顯示,但不統計
#按年度顯示
print(df.to_period('A').head()) #按年度顯示,但不統計
###2、asfreq()方法
#按年度頻率顯示
df_period.index.asfreq('A') # 'A'默認是'A-DEC',其他如'A-JAN'
#按季度頻率顯示
df_period.index.asfreq('Q') # 'Q'默認是'Q-DEC',其他如“Q-SEP”,“Q-FEB”
#按月度頻率顯示
df_period.index.asfreq('M') # 按月份顯示
#按工作日顯示
df_period.index.asfreq('B', how='start') # 按工作日期顯示
df_period.index.asfreq('B', how='end') # 按工作日期顯示
7、按日期統計數據
#按周統計數據
print(df.resample('w').sum().head()) # “w”,week
#按月統計數據
print(df.resample('M').sum().head())# "MS"是每個月第一天爲開始日期, "M"是每個月最後一天
#按季度統計數據
print(df.resample('Q').sum().head()) # "QS"是每個季度第一天爲開始日期, "Q"是每個季度最後一天
#按年統計數據
print(df.resample('AS').sum())# "AS"是每年第一天爲開始日期, "A是每年最後一天
8、按日期統計後,按年度或者季度、月份顯示
#按年統計並顯示
print(df.resample('AS').sum().to_period('A'))
#按季度統計並顯示
print(df.resample('Q').sum().to_period('Q').head())
#按月度統計並顯示
print(df.resample('M').sum().to_period('M').head())