pandas之數據運算


python科學計算的基本方式:

向量化運算(矢量化運算),並行計算,摒棄了循環遍歷(標量運算),浪費內存
衡量一個人會不會用pandas做數據分析

  1. 會不會做聚合推導透視表,交叉表
  2. 會不會矢量化編程完成項目

自定義運算
apply():Series和DataFrame通用自定義運算函數(計算行/列)
map():Series用
applymap():DataFrame用計算單元格
如果pandas庫自帶的運算和函數不滿足需求,可以自定義函數,並同時將函數應用到pandas的每行/列或值上
應用函數主要用於替代傳統的for循環
可以將map和apply的參數x理解為for循環的i值(series就是單值,DataFrame就是每一行/列)
針對Series的map函數,會將自定義函數應用到Series對象的每個值

不直接用於單元格的算法
關於行列的思路,分割成每個單元格作比較

參數傳遞

  • apply(top, n=1, column='math') 在apply函數內定義參數,幫助傳入top內 def top(aa,n,columns='english')

axis=0按行操作,默認  

  • 給這一列的所有行,進行運算

axis=1按列操作

  • 給這一行的所有列,進行運算
a = pd.Series([9,7,8,6],['a','b','c','d'])
b = pd.DataFrame(np.arange(20).reshape(4,5),index=['a','b','c','d'])

def ccc(x):
    return x.min()
b.apply(ccc, axis=0)   #給這一列的所有行,進行運算,所以結果和想的不一樣

# 自定義函數的參數x,用apply調用,在運算過程中標識DataFrame的1行或者1列(是series對象,可以理解為for循環遍歷,但是並行運算)
def bbb(x):
    return pd.Series([x.min(),x.max()],index=['min','max'])  #構建Series返回,結果就是返回DataFrame
b.apply(bbb)

 

基本統計函數
pandas的統計運算方法和numpy基本一致
默認針對0軸(行)做運算,大部分函數可加參數axis-1改為列運算

  1. describe() 針對0軸的統計匯總,計數/平均值/標准差/最小值/四分位數/最大值,非數值型列,不計入(字符串)指標
  2. sum()計算數據的總和,按針對0軸計算(各行計算),針對1軸計算參數改為1
  3. count() 非nan值數量
  4. mean()/median()/mode() 計算數據的算數平均值/中位數/眾數
  5. var()/std() 計算數據的方差/標准差
  6. min()/max() 計算數據的最大值/最小值
  7. idxmin()/idxmax() 計算數據的第一個最大值/最小值所在的位置索引,給索引切片使用(自定義索引,排除null/na等空值)

 

pandas分組聚合-基礎
數據分析階段
數據規律(清洗階段后),下一個階段就是分組聚合,分組聚合只針對數值類型

  • 對數據集分組並對各組應用一個函數是數據分析中的重要環境
  • 一般將數據准備好后,首先就是計算分組統計
  • sql能夠方便的連接,過濾。轉換和聚合數據,但sql能執行的分組運算種類優先,pandas則強大靈活很多

聚合操作,一般是指應用某種方法(自定義的聚合函數或者系統自帶的pandas的統計方法等)給數據降維

聚合函數常用

  •  平均值:mean() 透視表
  •  個數:size() 交叉表、

分組的作為行索引,聚合作為值(series),聚合作為列索引(DataFrame)

數據分組
分組聚合:groupby(),一般指以下一個或者多個操作步驟的集合
splitting 分組:將列分割為n組
applying 應用:將每個分組應用聚合函數
combining合並:合並分組和聚合的結果
name,score                       name ,score                  name ,score
a    1                            a     1,2                     a    2
a    2       ====>                b     3,4         ===>        b    4
b    3       group by name                         max(score)
b    4

以單列基准分組,聚合其他

a_values = [{"name": "鍾洋","chinese": 23,"math": 25,"english": 25,"test": "一"
},{"name": "李敏","chinese": 99,"math": 48,"english": 78,"test": "一"
},{"name": "夏軍","chinese": 70,"math": 83,"english": 12,"test": "一"
},{"name": "姚明","chinese": 65,"math": 12,"english": 73,"test": '二'
},{"name": "夏軍","chinese": 80,"math": 63,"english": 45,"test": '二'
},{"name": "夏軍","chinese": 90,"math": 82,"english": 65,"test": '三'
},{"name": "李帥","chinese": 99,"math": 58,"english": 78,"test": "一"}]
df = pd.DataFrame(a_values)

# 每位同學每課成績的平均分
# 分組
x = df.groupby('name').mean()
# 每位同學考試的次數
y = df.groupby('name').size()
# 將分組傳遞給變量
class_group = df.groupby('name')
class_group.size()
# 如果不想使用分組作為列索引,設置參數as_index=False
x = df.groupby('name',as_index=False).mean()

以多列為基准

  • 多列分組
  • 單列或多列聚合
# 單列多列分組
df.groupby('name').mean()
df.groupby(['name','test']).mean()

多列單列聚合

  • 對於大數據集,很可能值需要對部分進行聚合
  • 下面三種寫法結果一樣
  • 分組聚合參數,傳入標量形式得單個列名,返回Series
  • 分組聚合參數,傳入列表或數組,返回DataFrame(默認傳入所以列)
# 對除分組基准列以外得所有列進行聚合
df.groupby('name').sum()   # 多列聚合, 聚合除分組以外得所有列
# 分組后,只對chinese單列聚合
df['chinese'].groupby(df['name']).sum()   # 效率高,但是寫法詭異
df.groupby('name')['chinese'].sum()       # 書寫簡單,效率高,推薦,返回Series
df.groupby('name')[['chinese']].sum()       # 書寫簡單,效率高,推薦,返回DataFrame

# 分組后,多列聚合
df.groupby('name')['chinese'].sum()       # 書寫簡單,效率高,推薦

分組聚合進階

本質上 groupby傳入得數據並不是行索引或列索引,而是任意一個和數據結構對應得序列(布爾,列表,數組,字典,Series)

  • 根據列表做分組基准
  • 根據字典或者Series做分組基准
  • 根據函數做分組基准
  • 根據層次化索引得級別做分組基准
# 根據列表分組,列表值得個數必須和表格行或列數對應
df.groupby('name').size()   #分組參數是列索引,直接獲取某列得值
df.groupby(df['name']).size() #手動將列值傳入分組參數
###
df_list = ['aa','bb','cc','dd','ee','ff','gg']  # 自定義列表作為分組基准
df.groupby(df_list).size()
#set_index把其中一列作為行索引 
mapping = {'李敏':'one','姚明':'two'}
df2 = df.set_index('name')
df2.groupby(mapping).sum()
# 使用seies進行分組
df2.groupby(pd.Series(mapping)).size()

通過函數分組

  • 比起字典或者series,函數是一種更原生得方法定義分組映射
  • 任何被當作分組鍵得函數都會在各個索引值上被調用一次,其返回值就會被作用分組基准

  

people = pd.DataFrame(
    np.random.randn(5,5),
    columns=['a','bc','c','d','e'],
    index=['Joe','Steve','wes','jim','travis']
)
people.iloc[2:3,[1,2]] = np.nan

# len把行索引字符得個數作為分組基准
people.groupby(len).sum()
# 
a = [3,5,3,3,6]
people.groupby(a).sum()
#
ccc = ['one','one','one','two','two']
people.groupby([len,ccc]).sum()   #joe wes既有3個字符,又屬於one ,針對行索引做的分組

 

#使用函數分組
people.groupby(len,axis=1).sum()
#
zzz  = ['one','one','one','two','two']
people.groupby([len,zzz],axis=1).sum()

 

# lianxi,輸出每個學生在每次考次數中得數學平均分
從一個原始大表中抽取一個符合需求得小標

df.groupby(['name','test']).mean()   # 3維度
df.groupby(['name','test'])['math'].mean()   #2維Series
pd.DataFrame(df.groupby(['name','test'])['math'].mean() )
df.groupby(['name','test'])['math'].mean().unstack().fillna(0).astype(np.int)  #2維series轉換DataFrame
df.groupby(['name','test'])['math'].mean().unstack().fillna(0).astype(np.int)  #2維series轉換DataFrame
# 稱之為透視表
抽出1列,分組后作為行索引
抽出1列,分組后作為列索引
抽出1列,平均值聚合后作為值

  

 

根據層次化索引得級別分組
要根據層次化索引得級別,使用level關鍵字傳遞級別序號或名字

colums = pd.MultiIndex.from_arrays([['US','US','US','JP','JP',],[1,3,5,1,3]],names=['city','tenor'])
hier_df = pd.DataFrame(np.random.randn(4,5),columns=colums)
hier_df.groupby(level='city',axis=1).sum()   #默認按照行分組
# 按行分組,自定義布爾數組做分組基准
ddd = [True,True,False,False,False,False,True]
df.groupby(ddd).sum()
# 按照列分組
ddd = [True,True,False,False,False]
df.groupby(ddd,axis=1).sum()
# 按列分組,自定義布爾數組做分組基准
df.groupby(df.dtypes,axis=1).sum()
#假設以知列得分組關系后,並希望根據分組計算列得和
mapping={'a':'red','bc':'red','c':'bule','d':'bule','e':'red','f':'orange' } # 多寫或少寫不會執行,多了一個f,不會影響分組
people.groupby(mapping,axis=1).sum()

 


免責聲明!

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



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