Pandas模塊:表計算與數據分析

一 . pandas簡單介紹  

一、pandas是一個強大的Python數據分析的工具包。
二、pandas是基於NumPy構建的。php

三、pandas的主要功能html

  • 具有對其功能的數據結構DataFrame、Series
  • 集成時間序列功能
  • 提供豐富的數學運算和操做
  • 靈活處理缺失數據

四、安裝方法:pip install pandas
五、引用方法:import pandas as pdpython

二 . Series  

1 . Series  數組

  Series是一種相似於一維數組的對象 , 有下面兩部分組成 : 數據結構

    • values : 一組數據(ndarray類型)
    • index :  相關的數據索引標籤      

 

2 . series的建立 app

  1) . 由列表或numpy數組建立  : 默認索引爲 0 到 N-1 的整數 dom

  2) . 由字典建立 : 不能再使用index , 可是依然存在默認索引函數

     注意 : 數據源必須是一維數組工具

 

 

     二-1 . series特性   

1 . series 的索引post

   可使用中括號取單個索引(此時返回的是元素類型) , 或者中括號裏一個列表取多個索引(此時返回的是一個Series類型) . 

   (1) . 顯示索引 : 

    - 使用 index 中的元素做爲索引值 

    - 使用 s.loc [ ] (推薦) , 注意 : loc 中括號中放置的必定是顯示索引

    注意 : 此時是閉區間

 

   (2) . 隱式索引 : 

    - 使用整數做爲索引值 

    - 使用 .iloc [ ] (推薦) : iloc 中的括號中必需要放置隱式索引 

    注意 : 此時是半開區間

 

 

2 . 切片 

   (1) . 顯示索引切片 : index 和 loc

 

  (2) . 隱式索引切片 : 整數索引值 和 iloc 

 

3 . 基本概念 

   能夠把series當作是一個定長的有序字典 

  (1) . 向Series增長一行 , 至關於給字典增長一組鍵值對. 能夠經過 shape , size , index , values 等獲得 series的屬性 . 

  (2) . 可使用 .head() 和 .tail 分別查看前n個和後n個值

  

4 . 去重    

  .unique()

     二-2 . Series數據對齊  

1 . pandas在運算時,會按索引進行對齊而後運算,若是存在不一樣的索引,則結果的索引是兩個操做索引的並集.

2 . series 之間的運算

    1) .  + - * /

    2) . add() , sub() , mul() , div() , 

    注意 : 如何在兩個Series對象相加時將缺失值設爲0?

          sr1.add(sr2, fill_value=0)

    3) . 在運算中自動對齊不一樣索引的數據 , 若是索引對不齊,則補NaN  

 

     二-3 . Series數據缺失   

當索引沒有對應值的時候,可能會出現缺失數據顯示NaN的狀況

一、缺失數據:使用NaN(Not a Number)來表示缺失數據。其值等於np.nan。內置的None值也會被當作NaN處理。

二、處理缺失數據的相關方法:

  • dropna() 過濾掉值爲NaN的行
  • fillna() 填充缺失數據
  • isnull() 返回布爾數組,缺失值對應爲True
  • notnull() 返回布爾數組,缺失值對應爲False

 

三、過濾缺失數據:sr.dropna() 或 sr[data.notnull()]

四、填充缺失數據:fillna(0)

 

 

三 . DataFrame   

DataFrame是一個表格型的數據結構.

DataFrame由必定順序排列的多列數據組成
DataFrame既有行索引,也有列索引

  • 行索引:index
  • 列索引:columns
  • 值:values

     三-1 . DataFrame的建立 

   導包 :  from pandas import DataFrame

  最經常使用的方法是傳遞一個字典來建立。DataFrame以字典的鍵做爲每一【列】的名稱,以字典的值(一個數組)做爲每一列。

  此外,DataFrame會自動加上每一行的索引。

  使用字典建立的DataFrame後,則columns參數將不可被使用。

  同Series同樣,若傳入的列與字典的鍵不匹配,則相應的值爲NaN。

1 . 使用 ndarray 建立DataFrame 

2 . 使用 字典 建立 DataFrame

 

     三-2 . DataFrame查看數據  

查看數據經常使用屬性及方法:
        index                    獲取索引
        T                        轉置
        columns                    獲取列索引
        values                    獲取值數組
        describe()                獲取快速統計

    DataFrame各列name屬性:列名
    rename(columns={})     #字典建立不能用

 

     三-3 . DataFrame的索引與切片

  DataFrame有行索引和列索引。
  DataFrame一樣能夠經過標籤和位置兩種方法進行索引和切片。

DataFrame使用索引切片:

  •  方法1:兩個中括號,先取列再取行。 df['A'][0]
  • 方法2(推薦):使用loc/iloc屬性,一箇中括號,逗號隔開,先取行再取列。

  loc屬性:解釋爲標籤
  iloc屬性:解釋爲下標
向DataFrame對象中寫入值時只使用方法2
行/列索引部分能夠是常規索引、切片、布爾值索引、花式索引任意搭配。(注意:兩部分都是花式索引時結果可能與預料的不一樣)

 

 1 . DataFrame的索引 

  (1) . 對列進行索引

 

  (2) . 對行進行索引

    - 使用 .loc [] 加index來進行索引

    - 使用 .iloc [] 加整數來進行索引

    一樣返回一個 Series , index爲原來的 columns

 

  (3) . 對元素進行索引 

     - 使用列索引

    - 使用行索引(iloc[3,1] or loc['C','q']) 行索引在前,列索引在後

 

2 . 切片 

   注意 : 直接使用中括號時 : 

    - 索引表示列索引

    - 切片表示行切片

 

 

 

     三-4 .  DataFrame的運算

   DataFrame之間的運算同Series同樣

    - 在運算中自動對齊不一樣索引的數據

    - 若是索引不對應,則補NaN

 

 

     三-5 .  DataFrame的數據對齊和數據缺失

DataFrame對象在運算時,一樣會進行數據對齊,行索引與列索引分別對齊。
結果的行索引與列索引分別爲兩個操做數的行索引與列索引的並集。

注意 : 

  - None 

    None是Python自帶的,其類型爲python object。所以,None不能參與到任何計算中。

  - np.nan (NaN)

    np.nan是浮點類型,能參與到計算中。但計算的結果老是NaN。

案例 :  

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

 

DataFrame處理缺失數據的相關方法:

    • dropna(axis=0,where=‘any’,…) 過濾掉值爲NaN的行
      • 注意 : 在dropna中, axis=0 表示行,與常規相反
    • fillna() 填充缺失數據
      • 參數 : method 
        • bfill : 選擇向後填充(和後面數相同)  df.fillna(method='bfill',axis=1)
        • ffill  : 選擇向前填充    df.fillna(method='ffill',axis=1)
    • isnull() 返回布爾數組,缺失值對應爲True
      • 檢查條件 isnull.any(axis=1)
    • notnull() 返回布爾數組,缺失值對應爲False
      • 檢查條件 notnull.all(axis=1)  

 

 

     三-6 . 建立多層DataFrame  

  • 取得列:df['col'] df[[c1,c2]] df.loc[:,col]
  • 取行:df.loc['index'] df[index1:inde2]

1 . 隱式構造 

  最多見的方法是給DataFrame構造函數的index或者columns參數傳遞兩個或更多的數組

DataFrame(data=np.random.randint(0,100,size=(2,2)),columns=[['a','b'],['A','B']])

2 . 顯示構造 

  pd.MultiIndex.from_product

col=pd.MultiIndex.from_product([['qizhong','qimo'],
                                ['chinese','math']])

#建立DF對象
df = DataFrame(data=np.random.randint(60,120,size=(2,4)),index=['tom','jay'],
         columns=col)

 

 3 . 多層行索引 

   逐級降層

df['qimo']

df['qimo']['math']

 

# 獲取tom期中全部科目的考試成績

df['qizhong'].loc['tom']

 

注意
  在對行索引的時候,若一級行索引還有多個,對二級行索引會遇到問題!也就是說,沒法直接對二級索引進行索引,必須讓
二級索引變成一級索引後才能對其進行索引!
總結:
訪問一列或多列 直接用中括號[columnname]  [[columname1,columnname2...]]
訪問一行或多行  .loc[indexname]
訪問某一個元素  .loc[indexname,columnname]  獲取李四期中的php成績
行切片          .[index1:index2]        獲取張三李四的期中成績
列切片          .loc[:,column1:column2]    獲取張三李四期中的php和c++成績

 

      三-7 . 聚合操做

   所謂的聚合操做:平均數,方差,最大值,最小值…

df.sum(axis=0)

df.mean()

 

     三-8 . pandas的拼接操做  

pandas的拼接分爲兩種:

  • 級聯:pd.concat, pd.append
  • 合併:pd.merge, pd.join

1 . 使用pd.concat()級聯

  pandas使用pd.concat函數,與np.concatenate函數相似,只是多了一些參數:

objs
axis=0
keys
join='outer' / 'inner':表示的是級聯的方式,outer會將全部的項進行級聯(忽略匹配和不匹配),
           而inner只會將匹配的項級聯到一塊兒,不匹配的不級聯
ignore_index=False

 導包 : 

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

  (1) . 匹配級聯

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','d','c'],columns=['A','d','C'])

  (2) . 不匹配級聯

     不匹配指的是級聯的維度索引不一致.例如 : 縱向級聯時索引不一致,橫向級聯時索引不一致

     鏈接方式 : 

      • 外鏈接 : 補NaN (默認方式)
      • 內鏈接 : 只鏈接匹配的項           
pd.concat((df1,df2),axis=1,join='outer')  # 內鏈接

 

  (3) . 使用df.append() 函數添加   

   因爲在後面級聯的使用很是廣泛,所以有一個函數append專門用於在後面添加

df1.append(df2) #列索引必須一致

 

 2 . 使用 pd.merge() 合併

merge與concat的區別在於,merge須要依據某一共同的列來進行合併

使用pd.merge()合併時,會自動根據二者相同column名稱的那一列,做爲key來進行合併。

注意每一列元素的順序不要求一致

參數:

  • how:out取並集 inner取交集
  • on:當有多列相同的時候,可使用on來指定使用那一列進行合併,on的值爲一個列表

  (1) . 一對一合併  

df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
                'group':['Accounting','Engineering','Engineering'],
                })
df2 = DataFrame({'employee':['Lisa','Bob','Jake'],
                'hire_date':[2004,2008,2012],
                })
pd.merge(df1,df2) #自動找相同的,列進行合併

 

  (2) . 多對一合併

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,how='outer')

 left                                                                        right

   

  (3) . 多對多合併

df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
                 'group':['Accounting','Engineering','Engineering']})

df5 = DataFrame({'group':['Engineering','Engineering','HR'],
                'supervisor':['Carly','Guido','Steve']
                })

pd.merge(df1,df5,how='left')

 left                                                            right

   

 

   (4) . key 的規範化 

    • 當列衝突時,即有多個列名稱相同時,須要使用on=來指定哪個列做爲key,配合suffixes指定衝突列名
df1 = DataFrame({'employee':['Jack',"Summer","Steve"],
                 'group':['Accounting','Finance','Marketing']})

df2 = DataFrame({'employee':['Jack','Bob',"Jake"],
                 'hire_date':[2003,2009,2012],
                'group':['Accounting','sell','ceo']})

pd.merge(df1,df2,on='group',how='outer')

 

    • 當兩張表沒有可進行鏈接的列時,可以使用left_on和right_on手動指定merge中左右兩邊的哪一列列做爲鏈接的列
df1 = DataFrame({'employee':['Bobs','Linda','Bill'],
                'group':['Accounting','Product','Marketing'],
               'hire_date':[1998,2017,2018]})
df5 = DataFrame({'name':['Lisa','Bobs','Bill'],
                'hire_dates':[1998,2016,2007]})
display(df1,df5)

 

 

   (5) . 內合併與外合併 : out取並集 , inner取交集

    • 內合併 : 只保留二者都有的key(默認模式)
df6 = DataFrame({'name':['Peter','Paul','Mary'],
               'food':['fish','beans','bread']}
               )
df7 = DataFrame({'name':['Mary','Joseph'],
                'drink':['wine','beer']})
display(df6,df7)

    • 外合併 : how='outer' :  補NaN  
df6 = DataFrame({'name':['Peter','Paul','Mary'],
               'food':['fish','beans','bread']}
               )
df7 = DataFrame({'name':['Mary','Joseph'],
                'drink':['wine','beer']})
display(df6,df7)
pd.merge()

 

 

      三-9 . 數據處理  

1 . 刪除重複元素  : duplicated()

   使用duplicated()函數檢測重複的行,返回元素爲布爾類型的Series對象,每一個元素對應一行,若是該行不是第一次出現,則元素爲True

   - keep 參數 : 指定保留那一重複的行數據

# 建立具備重複元素行的DataFrame
import numpy as np
import pandas as pd
from pandas import Series,DataFrame

# 建立一個 df
np.random.seed(1)
df = DataFrame(data=np.random.randint(0,100,size=(8,6)))
df
#手動將df的某幾行設置成相同的內容
df.iloc[1] = [6,6,6,6,6,6]
df.iloc[3] = [6,6,6,6,6,6]
df.iloc[4] = [6,6,6,6,6,6]

 未變以前                                                          改變以後

 

   (1) . 方式一 : 

# 使用duplicated查看全部重複元素行
df.duplicated(keep='last') 

       

indexs = df[df.duplicated(keep='last')].index #獲取須要刪除行的索引
df.drop(labels=indexs,axis=0) #刪除重複行

  (2) . 方式二 : 

使用drop_duplicates()函數刪除重複的行

  • drop_duplicates(keep='first/last'/False)
df.drop_duplicates() #一步到位

 

 

2 . 映射 

 (1) . replace() 函數 : 替換元素

  使用replace()函數,對values進行映射操做

Series替換操做

  • 單值替換
    • 普通替換
    • 字典替換(推薦)
  • 多值替換
    • 列表替換
    • 字典替換(推薦)
  • 參數
    • to_replace:被替換的元素

replace參數說明:

  • method:對指定的值使用相鄰的值填充替換
  • limit:設定填充次數

DataFrame替換操做

  • 單值替換
    • 普通替換: 替換全部符合要求的元素:to_replace=15,value='e'
    • 按列指定單值替換: to_replace={列標籤:替換值} value='value'
  • 多值替換
    • 列表替換: to_replace=[] value=[]
    • 字典替換(推薦) to_replace={to_replace:value,to_replace:value}

注意:DataFrame中,沒法使用method和limit參數

df.replace(to_replace=6,value='six') #用'six'代替df中的'6'

df.replace(to_replace={3:6},value='six') #用'six'代替df中第4列的'6'

df.replace(to_replace={1:'one'}) #用'one'代替df中的''1'

 

 3 . map() 函數 : 

  新建一列 , map函數並非df的方法 , 而是series的方法 

  • map()能夠映射新一列數據
  • map()中可使用lambd表達式
  • map()中可使用方法,能夠是自定義的方法

    eg:map({to_replace:value})

注意 map()中不能使用sum之類的函數,for循環

dic = {
    'name':['周杰倫','李四','王五'],
    'salary':[1000,2000,3000]
}
df = DataFrame(data=dic)

 

#新增一列:給df中,添加一列,該列的值爲中文名對應的英文名

#封裝一個映射關係表
dic = {
    '周杰倫':'jay',
    '王五':'wangwu',
    '李四':'lisi'
}
df['ename'] = df['name'].map(dic)
df

 

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

  • 使用自定義函數
#自定義函數
def after_salary(s):
    if s <= 500:
        return s
    else:
        return s - (s-500)*0.5

#超過500部分的錢繳納50%的稅
after_sal = df['salary'].map(after_salary)
df['after_salary'] = after_sal
df
  • 使用lambda表達式
#員工的薪資集體提升500
df['salary'].map(lambda x:x+500)

 

 4 . 數據重排 --- 使用 .take() 函數排序

- take()函數接受一個索引列表,用數字表示,使得df根據列表中索引的順序進行排序
- eg:df.take([1,3,4,2,5])
  • np.random.permutation(x)能夠生成x個從0-(x-1)的隨機數列
df.take(np.random.permutation(1000),axis=0).take(np.random.permutation(3),axis=1)

#np.random.permutation(1000) :把0,1000隨機排列成列表

 當DataFrame規模足夠大時,直接使用np.random.permutation(x)函數,就配合take()函數實現隨機抽樣

5 . 數據分類處理 [重點]

數據聚合是數據處理的最後一步,一般是要使每個數組生成一個單一的數值。

數據分類處理:

  • 分組:先把數據分爲幾組
  • 用函數處理:爲不一樣組的數據應用不一樣的函數以轉換數據
  • 合併:把不一樣組獲得的結果合併起來

數據分類處理的核心:

 - groupby()函數
 - groups屬性查看分組狀況
 - eg: df.groupby(by='item').groups

 (1) . 分組

#數據源
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
                'price':[4,3,3,2.5,4,2],
               'color':['red','yellow','yellow','green','green','green'],
               'weight':[12,20,50,30,20,44]})

#分組
df.groupby(by='item')

#查看分組狀況
df.groupby(by='item').groups

 

分組後還能夠聚合 : sum , mean 

#計算出蘋果的平均價格
dic = {
    'Apple':3,
    'Banana':2.75,
    'Orange':3.5
}
df['mean_price'] = df['item'].map(dic)
df.groupby(by='item')['price'].mean()['Apple']

#按顏色查看各類顏色的水果的平均價格
df.groupby(by='color')['price'].mean()
dic={
    'green':2.83,
    'red':4,
    'yellow':3
}
df['color_mean_price'] = df['color'].map(dic)
df

 6 . 高級數據聚合 

  使用groupby分組後,也可使用transform和apply提供自定義函數實現更多的運算

  • df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
  • transform和apply都會進行運算,在transform或者apply中傳入函數便可
  • transform和apply也能夠傳入一個lambda表達式
#求出各類水果價格的平均值
df.groupby(by='item')['price'].mean()

 

apply和transform

#定義執行方法
def fun(s):
    sum = 0
    for i in s:
        sum+=s
    return sum/s.size
#使用apply函數求出水果的平均價格
df.groupby(by='item')['price'].apply(fun) #給fun傳入的參數是一個列表

#使用transform函數求出水果的平均價格
df.groupby(by='item')['price'].transform(fun) #給fun傳入的參數是一個列表
相關文章
相關標籤/搜索