Python之科學運算Pandas模塊


一、Series數列

Series
Series是一種類似與一維數組的對象,由下面兩個部分組成:
values:一組數據(ndarray類型)
index:相關的數據索引標簽

Series的創建
第一種:由列表或numpy數組創建
列表創建:
Series([1,2,3,4,5],index=['a','b','c','d','e'],name='Hello')
ndarray創建
a1 = np.array([1,2,3,4,5])
Series(a1,index=["a","b","c","d","e"],name='hello')
第二種:由字典創建:不能在使用index.但是依然存在默認索引
注意:數據源必須為一維數據
dict = {'hello':12,'hey':30}
Series(data=dict)

Series的索引
可以使用中括號取單個索引(此時返回的是指定索引的元素),或者中括號里一個列表取多個索引(此時返回的是一個Series類型)。
s1 = Series(data=[1,2,3],index=['a','b','c'])
----> s1[1] 返回的是指定索引的元素
----> s1[[0,1]] 返回的是一個Series類型
顯式索引:
使用index中的元素作為索引值,
使用s.loc[](推薦):注意,loc中括號中放置的一定是顯示索引
----> s1.b
----> s1.loc["b"]
隱式索引
使用.iloc[](推薦):iloc中的中括號中必須放置隱式索引
----> s1.iloc[1]

Series切片:隱式索引切片和顯示索引切片
顯示索引切片:index和loc
s1["a":"c"]根據index切
s1.loc["a":"c"]根據loc切
隱示索引切片:整數索引值和iloc
s1[0:2]根據整數索引值切
s1.iloc[0:2]根據iloc切

Series的基本概念
可以把Series看成一個定長的有序字典
向Series增加一行:相當於給字典增加一組鍵值對

可以通過shapesizeindex,values等得到series的屬性

可以使用s.head(n),tail(n)分別查看前n個和后n個值

當索引沒有對應的值時,可能出現缺失數據顯示NaN(not a number)的情況

可以使用pd.isnull()pd.notnull(),或s.isnull(),notnull()函數檢測缺失數據

 
屏幕快照 2018-11-05 下午8.44.28.png

 

Series的運算
+ - * /
add()/sub()/mul()/div()
s1.div(s2,fill_value=9)
在運算中自動對齊不同索引的數據,如果索引不對應,則補NaN

二、DataFarme(數據幀)

DataFarme認識
DataFrame是一個【表格型】的數據結構。DataFrame由按一定順序排列的多列數據組成。設計初衷是將Series的使用場景從一維拓展到多維。DataFrame既有行索引,也有列索引。
行索引:index
列索引:columns
值:values

DataFrame(數據幀)的創建
最常用的方法是傳遞一個字典來創建。DataFrame以字典的鍵作為每一【列】的名稱,以字典的值(一個數組)作為每一列。
此外,DataFrame會自動加上每一行的索引。
使用字典創建的DataFrame后,則columns參數將不可被使用。
同Series一樣,若傳入的列與字典的鍵不匹配,則相應的值為NaN。
使用字典創建DataFarme
dict = {"java":[90,22,66],'python':[12,33,66]}
DataFrame(data=dict,index=['章傘','里斯','魍伍'])
使用ndarray創建DataFrame
DataFrame(data=np.random.randint(0,100,size=(3,6)),index=["one","two","three"],columns=["呵","哈","嘿","嘻","嗨","嗚"])

DataFarme屬性
DataFrame屬性:values、columns、index、shape

DataFrame的索引

對列進行索引
-- 通過類似字典的方式 df['q']
-- 通過屬性的方式 df.q
可以將DataFrame的列獲取為一個Series。返回的Series擁有原DataFrame相同的索引,且name屬性也已經設置好了,就是相應的列名。
--- df["呵"]
--- df.呵
--- df[["呵","哈","嘿"]]
修改列索引
df.columns = ['1','2','3',"4","5","6"]

對行進行索引
使用.loc[]加index來進行行索引
使用.iloc[]加整數來進行行索引
同樣返回一個Series,index為原來的columns。
--- df.loc["one"]
--- df.loc[["one","two"]]
--- df.loc["one":"three"]
--- df["one":"three"]
--- df["one":"three"]["嘿"]
修改行索引
--- df.index = [1,2,3]

對元素索引的方法
行索引在前,列索引在后
--- df.loc["one"]["哈"]
--- df.iloc[0]["哈"]

DataFrame的列刪除
df.drop("列名",axio=1,inplace=True)

DataFarme的切片
--- df.loc["one":"three","呵":"嘿"]
--- df.loc["one":"two"][["呵","嗚"]]
--- df.loc["one":"two",["呵","嗚","哈"]]
--- df.loc[["one"],["呵","嗚","哈"]]

DataFrame的運算
同Series一樣:
在運算中自動對齊不同索引的數據
如果索引不對應,則補NaN

處理丟失數據
有兩種丟失數據:None、np.nan(NaN)
None是Python自帶的,其類型為python object。因此,None不能參與到任何計算中。
np.nan是浮點類型,能參與到計算中。但計算的結果總是NaN。

pandas中None與np.nan都視作np.nan

pandas處理空值操作
isnull(). 判斷函數
notnull() 判斷函數
dropna(): 過濾丟失數據
df.dropna() 可以選擇過濾的是行還是列(默認為行):axis中0表示行,1表示的列
fillna(): 填充丟失數據
很多時候將空值全都dropna()掉是不現實的,所以需要用fillna()填充空值。
df.fillna(value=100) 或者 df.fillna(method="ffill",axis=0)
method 控制填充的方式,可以選擇前向填充還是后向填充

DataFrame的數據過濾
df.query(expr, inplace=False, **kwargs),可以指定一個字符串形式的篩選條件 邏輯與& 或 | ==

df.shift() 該函數主要的功能就是使數據框中數據整體移動
df.shift(1)

三、創建多層列索引

隱式構造
最常見的方法是給DataFrame構造函數的index或者columns參數傳遞兩個或更多的數組
df = DataFrame(data=np.random.randint(80,100,size=(2,4)),index=['tom','jay'],columns=[['qz','qz','qm','qm'],['chinese','math','chinese','math']])

顯示構造pd.MultiIndex.from_
使用數組方式
創建了一個索引對象,該索引對象為二層索引
indexObj = pd.MultiIndex.from_arrays([['qz','qz','qm','qm'],['chinese','math','chinese','math']])
創建DF對象
DataFrame(data=np.random.randint(80,100,size=(2,4)),index=['tom','jar'],columns=indexObj)

 
屏幕快照 2018-11-05 下午10.00.20.png

使用product方式

 

最簡單,推薦使用
col=pd.MultiIndex.from_product([['qizhong','qimo'], ['chinese','math']])
創建DF對象
df = DataFrame(data=np.random.randint(10,100,size=(2,4)),index=['tom','jay'], columns=col)

 
屏幕快照 2018-11-05 下午10.05.06.png

 

多層行索引
除了列索引,行索引也能用上述同樣的方法創建多層行索引

多層索引對象的索引與切片操作
注意在對行索引的時候,若一級行索引還有多個,對二級行索引會遇到問題!也就是說,無法直接對二級索引進行索引,必須讓二級索引變成一級索引后才能對其進行索引!

總結:
訪問一列或多列 直接用中括號[columnname] 、[[columname1,columnname2...]]
訪問一行或多行 .loc[indexname]
訪問某一個元素 .loc[indexname,columnname]
行切片 .loc[index1:index2]
列切片 .loc[:,column1:column2]

聚合操作
所謂的聚合操作:平均數,方差,最大值,最小值……
使用value_counts()函數,統計列中各個元素出現次數
使用unique()函數查看一列中有哪些元素

四、pandas的拼接操作(類似數據庫的聯表)

pandas的拼接分為兩種:
級聯:pd.concat, pd.append
合並:pd.merge, pd.join

----級聯

pandas使用pd.concat級聯函數,與np.concatenate函數類似,只是多了一些參數:
objs 級聯的對象
axis=0 軸向
keys:列表,列表元素表示的是進行級聯的df的一個名稱
join='outer' / 'inner':表示的是級聯的方式,outer會將所有的項進行級聯(忽略匹配和不匹配),而inner只會將匹配的項級聯到一起,不匹配的不級聯
ignore_index=False

匹配級聯
df1 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','b','c'],columns=['A','B','C'])
pd.concat([df1,df1],axis=0)
不匹配級聯
不匹配指的是級聯的維度的索引不一致。例如縱向級聯時列索引不一致,橫向級聯時行索引不一致
不匹配級聯有2種連接方式:
外連接:補NaN(默認模式)
內連接:只連接匹配的項
df1 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','b','c'],columns=['A','B','C'])
df2 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','c','d'],columns=['A','C','D'])
外鏈接pd.concat([df1,df2],axis=1,join="outer")
內鏈接pd.concat([df1,df2],axis=0,join="inner")
內鏈接指定keyspd.concat([df1,df2],axis=1,join="inner",keys=['AAA','BBB'])

df.append()函數級聯
由於在后面級聯的使用非常普遍,因此有一個函數append專門用於在后面添加
df1.append(df2)

----合並

使用pd.merge()合並
merge與concat的區別在於,merge需要依據某一共同的列來進行合並
使用pd.merge()合並時,會自動根據兩者相同column名稱的那一列,作為key來進行合並。
注意每一列元素的順序不要求一致

參數
how:out取並集 inner取交集
on:當有多列相同的時候,可以使用on來指定使用那一列進行合並,on的值為一個列表
一對一合並
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],'group':['Accounting','Engineering','Engineering'],})
df2 = DataFrame({'employee':['Lisa','Bob','Jake'],'hire_date':[2004,2008,2012],})
merge合並:pd.merge(df1,df2)
多對一合並
df3 = DataFrame({'employee':['Lisa','Jake'],'group':['Accounting','Engineering'],'hire_date':[2004,2016]})
df4 = DataFrame({'group':['Accounting','Engineering','Engineering'],'supervisor':['Carly','Guido','Steve']})
pd.merge(df3,df4)
多對多合並

key的規范化使用
當列沖突時,即有多個列名稱相同時,需要使用on=來指定哪一個列作為key,配合suffixes指定沖突列名。
pd.merge(df1,df2,on="group",suffixes=('_甲','乙'),how="outer")

注意:當兩張表沒有可進行連接的列時,可使用left_on和right_on手動指定merge中左右兩邊的哪一列列作為連接的列

內合並與外合並:
外合並outer:取並集,補NaN
內合並inner:取交集,保留兩者都有的key

五、pandas數據處理

1、檢測重復行 duplicated()
  使用duplicated()函數檢測重復的行,返回元素為布爾類型的Series對象,每個元素對應一行,如果該行不是第一次出現,則元素為True
keep參數:指定保留哪一重復的行數據
True 重復的行

2.刪除重復行 drop_duplicates()
  使用drop_duplicates()函數刪除重復的行
  drop_duplicates(keep='first/last'/False)

2. 映射:指定替換
  replace()函數:替換元素
  使用replace()函數,對values進行映射操作

Series替換操作replace()
單值替換
  普通替換
  s.replace(to_replace=2,value='two',inplace=True)
  字典替換(推薦)
  s.replace(to_replace={2:'two'},inplace=True)
多值替換
  列表替換
  s.replace(to_replace=[1,5],value=['one','five'])
  字典替換(推薦)
  s.replace(to_replace={3:'three',4:'four'},inplace=True)
參數
  to_replace:被替換的元素
  method:對指定的值使用相鄰的值填充替換
  limit:設定填充次數

DataFrame替換操作
單值替換
  普通替換: 替換所有符合要求的元素,沒有要替換的值也不會報錯:
  df.replace(to_replace=64,value='aaa')
  按列指定單值替換: to_replace={列標簽:替換值} ,value='value'
  df.replace(to_replace={2:85},value='eight')
多值替換
  列表替換: to_replace=[] value=[]
  df.replace(to_replace=[9,0],value=['a','b'])
  字典替換(推薦) to_replace={to_replace:value,to_replace:value}
  df.replace(to_replace={1:"one",30:"thirty"})
注意:DataFrame中,無法使用method和limit參數

3. map()函數:新建一列
  map是Series的一個函數
  map()可以映射新一列數據
  map()中可以使用lambd表達式
  map()中可以使用方法,可以是自定義的方法
注意 map()中不能使用sum之類的函數,for循環
df = DataFrame(data=[['zhangsan',1000,'sale'],['lisi',2000,'dev'],['wangwu',3333,'dev']],columns=['name','salary','dep'])
增加名為e_name列:
df['e_name'] = df['name'].map({'lisi':'Tony','zhangsan':'Tom','wangwu':'Jerry'})

map當做一種運算工具,至於執行何種運算,是由map函數的參數決定的
(參數:lambda,函數)

-- 使用自定義函數
  def func():
    ...
    return xxx
  df['salary'].map(func)
-- 使用lambda表達式
  df['salary'].map(lamada x:x..)

注意:並不是任何形式的函數都可以作為map的參數。只有當一個函數具有一個參數且有返回值,那么該函數才可以作為map的參數。

4. 使用聚合操作對數據異常值檢測和過濾
使用df.std()函數可以求得DataFrame對象每一列的標准差
此處不再做詳細解讀

5. 排序
--使用sort_value()排序
d f.sort_values(by="列名",axis=0,ascending=False)
-- 使用.take()函數排序
take()函數接受一個索引列表,用數字表示,使得df根據列表中索引的順序進行排序
df.take([1,2,0],axis=0)

 
屏幕快照 2018-11-06 下午8.14.29.png

-- 可以借助np.random.permutation()函數隨機排序
np.random.permutation(x)可以生成x個從0-(x-1)的隨機數列
arr = np.random.permutation(4)
df.take(arr,axis=1)
隨機抽樣:當DataFrame規模足夠大時,直接使用np.random.permutation(x)函數,就配合take()函數實現隨機抽樣

 

6.數據分類處理【重點】
數據聚合是數據處理的最后一步,通常是要使每一個數組生成一個單一的數值。

數據分類處理:
  分組:先把數據分為幾組
  用函數處理:為不同組的數據應用不同的函數以轉換數據
  合並:把不同組得到的結果合並起來
數據分類處理的核心:
  groupby()函數
  groups屬性查看分組情況
分組后的聚合操作:分組后的成員中可以被進行運算的值會進行運算,不能被運算的值不進行運算

unstack()與reset_index()對比:
針對多列分組情況,使用unstack(level=1)將上面所得分組數據指定的索引變成列索引。

 
屏幕快照 2018-11-07 下午4.05.50.png

把索引變成列,Series.reset_index()
 
屏幕快照 2018-11-07 下午4.16.23.png

 

pandas數據讀取和寫入:

1.pandas提供了一些用於將表格型數據讀取為DataFrame對象的函數,期中read_csv和read_table這兩個使用最多。
2.使用read_csv讀取url獲取網絡上的數據
3.通過to_excel(path)、to_sql("sql語句",conn)等方式將數據寫入對應的文件或數據庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM