程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Pandas數據處理

編輯:Python
數據預覽
  • 首先,調用read_excel()方法讀取數據

    import pandas as pd
    df = pd.read_excel("data.xlsx")
    df
    姓名 班級 語文 數學
    0 張三 一班 99 90
    1 李四 一班 78 NaN
    2 王五 一班 70 88
    3 小明 二班 88 99
    4 小紅 二班 98 77
    
  • 導入數據後,首先要熟悉數據。

    • shape屬性:可以幫助我們查看數據包含幾行幾列

      df.shape
      (5,4)
      

      從結果可以看出,這份數據一共有5行4列

    • **head()tail()**方法:head()方法可以幫助我們查看數據的前幾行,tail()方法可以幫助我們查看數據的後幾行

      df.head()
      姓名 班級 語文 數學
      0 張三 一班 99 90
      1 李四 一班 78 NaN
      2 王五 一班 70 88
      3 小明 二班 88 99
      4 小紅 二班 98 77
      df.tail(2)
      姓名 班級 語文 數學
      3 小明 二班 88 99
      4 小紅 二班 98 77
      

      head()方法默認展示的是前5行數據,tail()方法默認展示的是後5行數據。當他們傳入指定數字時,就可以幫我們獲取指定的行數。

    • dtypes屬性:可以幫助我們查看每列數據的數據類型

      df.dtypes
      姓名 object
      班級 object
      語文 int64
      數學 int64
      dtype object
      

      object類型是字符串,int64是整型,float64是浮點型

    • **describe()**方法:可以幫助我們查看數值型變量的描述性統計量

      df.describe()
      語文 數學
      count
      mean
      std
      min
      25%
      50%
      75%
      max
      

      count表示計數,mean表示平均值,std表示標准差,minmax分別表示最小值和最大值,25%50%75%表示四分位數

    • **info()**方法:可以幫助我們查看數據的列名、數據類型、非空值、以及內存占用情況

      df.info()
      <class "pandas.core.frame.DataFrame">
      RangeIndex: 6 entries, 0 to 5
      Data columns (total 5 columns):
      # Column Non-Null Count Dtype
      -- ----- ------- ----- -----
      0 姓名 6 non-null object
      1 班級 6 non-null object
      2 語文 6 non-null int64
      3 數學 5 non-null int64
      dtypes: int64(2),object(2)
      memory usage: 368.0+ bytes
      

      可以清楚的看到每一個列字段的列名、非空值和數據類型。另外“數學”這一列只有5個非空值,表明該列存在缺失值。同時memory usage為我們展示了這份數據占用內存的大小

數據預處理

通過數據預覽,可以做到對數據心中有數。然而,在正式進行數據處理之前,我們必須進行數據預處理,它直接關系到分析結果的准確性。

有些數據會存在缺失值(NaN)、重復值

  • 檢測缺失值

    • 其實檢測缺失值最簡單的方法就是調用**info()**方法,通過觀察每一列的非空值,即可判斷出哪些列存在缺失值

    • 另外還有一種檢測是否存在缺失值的方法,即**isnull()方法搭配any()**方法,具體介紹如下

      • isnull():對於缺失值,返回True;對於非缺失值,返回False

      • any():一個序列中有一個True,則返回True,否則返回False

        df.isnull() ###打印出每個數據的True或False值
        姓名 班級 語文 數學 英語
        0 False False False False False
        1 False False False True False
        2 False False False False False
        3 False False False False False
        4 False False False False False
        5 False False False False False
        df.isnull().any(axis=1) ###axis=1,可以幫助我們打印出每一行是否存在缺失值
        0 False
        1 True
        2 False
        3 False
        4 False
        5 False
        df.isnull().any() ###不指定打印的是每一列 是否存在缺失值
        姓名 False
        班級 False
        語文 False
        數學 True
        英語 False
        
  • 檢測重復值

    • 調用**duplicated()**方法,可以用於檢測重復值

      df.duplicated()
      0 False
      1 False
      2 True
      3 False
      4 False
      5 False
      df.duplicated().any()
      True
      

      調用duplicated()方法,可以返回某一行是否是重復值。由於第4行和第3行的數據屬於重復行,因此返回True。接著使用any()方法,即可判斷出數據中存在重復值

  • 缺失值處理

    • 通常使用NaN表示缺失值。如果存在缺失值,我們可以調用**fillna()方法來填充數據。也可以用dropna()**方法刪除缺失值

      df = df.fillna(0) ###將NaN修改為0
      df = df.dropna() ###將有缺失值的一行刪除
      
  • 重復值處理

    • **drop_duplicates()**方法,它可以對所有值進行重復值判斷,並默認保留第一個(行)值

      df
      姓名 年齡
      0 張三 19
      1 張三 19
      2 李四 20
      df = df.drop_duplicates()
      姓名 年齡
      0 張三 19
      2 李四 20
      

      可以幫我們刪除重復行,只保留第一行的數據

  • 數據替換

    • 調用**replace()**方法,可以實現數據替換,例如replace(A,B),表示直接將A替換成B

      df['數學'] = df['數學'].replace(0,90)
      
數據選取
  • 按行/列篩選,lociloc兩種方法,用於行/列篩選

    • loc:利用標簽索引的方式獲取行或列

    • iloc:利用位置索引的方式獲取行或列

      選取一列
      df['f']
      df.loc[:,'f']
      df.iloc[:,[1]]
      選取多列
      df[['e','f']]
      df.loc[:,['e','f']]
      df.iloc[:,[0,1]]
      選取一行
      df.loc['b',:]
      df.iloc[1,:]
      選取多行
      df.loc[['a','b'],:]
      df.iloc[[0,1],:]
      同時選取行列
      df.loc['b','f']
      df.iloc[1,1]
      同時選取多行多列
      df.loc[['a','b'],['f','g']]
      df.iloc[[0,1],[1,2]]
      
      df = df.set_index("姓名")
      df
      班級 語文 數學 英語
      姓名
      趙一 一班 98 96.0 97
      王二 一班 88 90.0 75
      張三 一班 86 87.0 93
      李四 二班 93 92.0 81
      朱五 二班 95 99.0 60
      df.loc[['趙一','李四']]
      班級 語文 數學 英語
      姓名
      趙一 一班 98 96.0 97
      李四 二班 93 92.0 81
      df.iloc[[0,3]]
      班級 語文 數學 英語
      姓名
      趙一 一班 98 96.0 97
      李四 二班 93 92.0 81
      

      調用set_index()方法,我們將數據框中的“姓名“列設置為新的索引。我們既可以用loc傳入標簽索引的方式,獲取這兩位同學的數據信息,也可以用iloc傳入位置索引的方式獲取信息

  • 按條件篩選,有時候我們想要篩選出符合某些條件的數據,提供了**query()isin()between()**

    • 篩選數學成績在95分以上的同學

      df[df['數學']>95]
      
    • 篩選語文和數學成績都在90分以上的同學

      df.query("語文>90 & 數學>90")
      
    • 篩選語文成績是88或95的同學

      df[df['語文'].isin(['88','95'])]
      
    • 篩選數學成績在85到95之間的同學

      df[df['數學'].between(85,95)] ###不包含邊界值85和95
      
數據運算
方法作用方法作用sum()求和abs()求絕對值count()計數mod()求余數mean()求均值value_counts()求每個值出現的個數max()求最大值prod()求連乘積min()求最小值argmax()求最大值的索引值mode()求眾數idxmax()求最大值的索引值var()求方差argmin()求最小值的索引值std()求標准差idxmin()求最小值的索引值median()求中位數unique()去重(唯一值)
  • 計算每個人的總成績

    df['總分'] = df['語文'] + df['數學'] + df['英語']
    df
    姓名 班級 語文 數學 英語 總分
    0 趙一 一班 98 96.0 97 291.0
    1 王二 一班 88 90.0 75 253.0
    2 張三 一班 86 87.0 93 266.0
    3 李四 二班 93 92.0 81 266.0
    4 朱五 二班 95 99.0 60 254.0
    
  • 如果想計算出每個班級的總人數,應該怎麼做

    df['班級'].value_counts()
    一班 3
    二班 2
    Name: 班級, dtype:int64
    
  • 計算出每個人的平均分,並保留兩位小數

    df['平均分']=df['總分'].apply(lambda x: round(x/3,2))
    df
    姓名 班級 語文 數學 英語 總分 平均分
    0 趙一 一班 98 96.0 97 291.0 97.00
    1 王二 一班 88 90.0 75 253.0 84.33
    2 張三 一班 86 87.0 93 266.0 88.67
    3 李四 二班 93 92.0 81 266.0 88.67
    4 朱五 二班 95 99.0 60 254.0 84.67
    

    apply()將”總分“這一列的每個元素,都除以3且結果保留兩位小數。

    相當於

    a=[1,2,3,4,5]
    c=list(map(lambda x:x-1,a))
    print(c)
    [0, 1, 2, 3, 4]
    
  • 數據排序與排名

    • 數據排序:sort_value()方法可以實現

      DataFrame.sort_value(by,ascending,inplace)
      by:列名(字符/字符列表)
      ascending:是否升序排序,默認為升序:True
      inplace:是否修改原DataFrame
      
    • 按照總分降序排序

      df.sort_values(by = ["總分"],ascending=False,inplace=True)
      df
      姓名 班級 語文 數學 英語 總分 平均分
      0 趙一 一班 98 96.0 97 291.0 97.00
      2 張三 一班 86 87.0 93 266.0 88.67
      3 李四 二班 93 92.0 81 266.0 88.67
      4 朱五 二班 95 99.0 60 254.0 84.67
      1 王二 一班 88 90.0 75 253.0 84.33
      ###如果總分相同,再按英語來排序
      df.sort_values(by = ["總分","英語"],ascending=[False,True],inplace=True)
      df
      姓名 班級 語文 數學 英語 總分 平均分
      0 趙一 一班 98 96.0 97 291.0 97.00
      3 李四 二班 93 92.0 81 266.0 88.67
      2 張三 一班 86 87.0 93 266.0 88.67
      4 朱五 二班 95 99.0 60 254.0 84.67
      1 王二 一班 88 90.0 75 253.0 84.33
      
    • 數據排名

      • 當我們對數據完成排序後,就可以進行數據排名了。調用rank()方法可以實現。

        DataFrame.rank(method,ascending)
        method:排序方式
        ascending:是否升序排序,默認為True
        
      • method有5個常用選項

        • first

          姓名總分排名趙一2911張三2662李四2663朱五2544王二2535
        • average

          姓名總分排名趙一2911張三2662.5李四2662.5朱五2544王二2535
        • min

          姓名總分排名趙一2911張三2662李四2662朱五2544王二2535
        • max

          姓名總分排名趙一2911張三2663李四2663朱五2544王二2535
        • dense

          姓名總分排名趙一2911張三2662李四2662朱五2543王二2534
    • 按照總分來排名

      df['排名'] = df['總分'].rank(method='dense',ascending=False).astype('int')
      df
      姓名 班級 語文 數學 英語 總分 平均分 排名
      0 趙一 一班 98 96.0 97 291.0 97.00 1
      2 張三 一班 86 87.0 93 266.0 88.67 2
      3 李四 二班 93 92.0 81 266.0 88.67 2
      4 朱五 二班 95 99.0 60 254.0 84.67 3
      1 王二 一班 88 90.0 75 253.0 84.33 4
      

      由於這裡返回的排名值是一個浮點型,因此需要調用astype()方法實現數據類型轉換

  • 數據合並與連接:用於實現對多表的操作

    • 數據合並:將同種性質表的不同部分合並在一起,一般不需要考慮公共列

      • 分為橫向合並和縱向合並兩種方式。使用concat()方法

        df
        a b c
        0 10 20 30
        1 40 50 60
        2 70 80 90
        df2
        d
        0 35
        1 65
        2 95
        ###橫向合並
        df_concat=pd.concat([df,df2],axis=1)
        df_concat
        a b c d
        0 10 20 30 35
        1 40 50 60 65
        2 70 80 90 95
        df3
        a b c
        0 110 120 130
        ###縱向合並,使用reset_index()可以幫助我們重置合並後的索引。不然就是 0 1 2 0
        df_concat=pd.concat([df,df3],axis=0).reset_index(drop=True)
        df_concat
        a b c
        0 10 20 30
        1 40 50 60
        2 70 80 90
        3 110 120 130
        
      • 如果想要加入學生信息表的數據

        df3 = pd.read_excel("學生信息表.xlsx")
        df3
        姓名 性別 住址
        0 王二 男 朝陽
        1 李四 女 朝陽
        2 朱五 男 海澱
        3 黃七 男 海澱
        4 趙一 女 朝陽
        5 馬六 女 海澱
        6 張三 男 海澱
        pd.concat([df_concat,df3],axis=1)
        姓名 班級 語文 數學 英語 姓名 性別 住址
        0 趙一 一班 98 96.0 97 王二 男 朝陽
        1 王二 一班 88 90.0 75 李四 女 朝陽
        2 張三 一班 86 87.0 93 朱五 男 海澱
        3 李四 二班 93 92.0 81 黃七 男 海澱
        4 朱五 二班 95 99.0 60 趙一 女 朝陽
        5 馬六 三班 86 90 89 馬六 女 海澱
        6 黃七 三班 96 88 91 張三 男 海澱
        由於concat()方法合並數據依賴索引,當兩表的數據順序不一致時,就會產生這類錯誤,姓名對不上。
        要想規避,以姓名為連接鍵
        
    • 數據連接:將不同性質表連接在一起,一般需要考慮公共列

      • 調用merge()方法實現數據連接

        pd.merge(left,right,how,on)
        left:左側DataFrame對象
        right:右側DataFrame對象
        how:數據合並的方式
        on:連接鍵
        
      • 兩個數據框DataFrame想要進行數據連接,需要依賴某個“公共列”作為連接鍵,數據連接後的結果受參數how的影響

        • how=“left”:左表中的數據都會展示出來,右表會根據連接鍵將數據連接到左表上,對於不符合條件的數據用NaN補充(左連接)
        • how=“right”:右表中的數據都會展示出來,左表會根據連接鍵將數據連接到左表上,對於不符合條件的數據用NaN補充(右連接)
        • how=“inner”:參數的默認值,顯示左表和右表中連接鍵都存在的數據(內連接)
        • how=“outer”:保留兩個表的所有信息(全連接)
        df
        a b c
        0 10 20 30
        1 40 50 60
        2 70 80 90
        df2
        a d
        0 10 35
        1 40 65
        2 75 95
        pd.merge(df,df2,how='left',on='a')
        a b c d
        0 10 20 30 35
        1 40 50 60 65
        2 70 80 90 NaN
        pd.merge(df,df2,how='right',on='a')
        a b c d
        0 10 20 30 35
        1 40 50 60 65
        2 75 NaN NaN 95
        pd.merge(df,df2,how='inner',on='a')
        a b c d
        0 10 20 30 35
        1 40 50 60 65
        pd.merge(df,df2,how='outer',on='a')
        a b c d
        0 10 20 30 35
        1 40 50 60 65
        2 70 80 90 NaN
        3 75 NaN NaN 95
        
  • 數據分組與透視表

    • 通過合並和連接得到的大表,一般用於“數據分組”和“數據透視表”的計算

      DataFrame.groupby(by).聚合函數
      by:分組依據
      
    • 一般分組和聚合是搭配使用的,分組後調用聚合函數完成聚合操作

      函數作用函數作用sum()求和median()求中位數count()計數var()求方差mean()求平均值std()求標准差max()求最大值describe()計算描述性統計量min()求最小值first第一次出現的值mode()求眾數last最後一次出現的值
    • 以班級分組,計算每個班級的學生數量

      df_merge = pd.merge(df_concat,df3,how='inner',on='姓名')
      df_merge
      姓名 班級 語文 數學 英語 性別 住址
      0 趙一 一班 98 96.0 97 男 朝陽
      1 王二 一班 88 90.0 75 女 朝陽
      2 張三 一班 86 87.0 93 男 海澱
      3 李四 二班 93 92.0 81 男 海澱
      4 朱五 二班 95 99.0 60 女 朝陽
      5 馬六 三班 86 90 89 女 海澱
      6 黃七 三班 96 88 91 男 海澱
      df_merge.groupby("班級").count()
      姓名 語文 數學 英語 性別 住址
      班級
      一班 3 3 3 3 3 3
      二班 2 2 2 2 2 2
      三班 2 2 2 2 2 2
      df_merge.groupby("班級")['姓名'].count()
      班級
      一班 3
      二班 2
      三班 2
      Name:姓名,dtype:int64
      

      調用groupby()方法並搭配聚合函數count(),按照班級這列進行分組並對其他列進行計數,統計出每個班級的學生數量,實際上只需要對姓名這列計數就夠了。

    • 以班級、住址分組

      df_merge.groupby(['班級','住址'])['姓名'].count()
      班級 住址
      一班 朝陽 2
      海澱 1
      二班 朝陽 1
      海澱 1
      三班 海澱 2
      Name:姓名,dtype:int64
      
    • 以班級分組,計算每個班語文成績最高的分數

      df_merge.group("班級")['語文'].max()
      班級
      一班 98
      二班 96
      三班 95
      Name:語文,dtype:int64
      
  • 數據透視表:pivot_table()可以實現數據透視表

    參數作用data相當於Excel中的“選中數據源”index相當於數據透視表字段中的行columns相當於數據透視表字段中的列values相當於數據透視表字段中的值aggfunc相當於計算類型margins相當於結果中的總計margins_name相當於修改總計名fill_value將缺失值用某個指定值填充
    • 以住址為行,班級為列,計算每個班級的學生數量,並統計他們的合計值

      pd.pivot_table(
      df_merge,values="姓名",
      columns="班級",index="住址",
      aggfunc="count",fill_value=0,
      margins_name='合計',margins=True
      )
      班級 一班 二班 三班 合計
      住址
      朝陽 2 1 0 3
      海澱 1 1 2 4
      合計 3 2 2 7
      
  • Excel拆分與合並

    • 按條件將Excel文件拆分到不同的工作簿

      import pandas as pd
      df = pd.read_excel("三年級總成績單.xlsx")
      for i in df['班級'].unique():
      df[df['班級']==i].to_excel(f"{i}.xlsx",index=False)
      
    • 按條件將Excel拆分到不同的工作表

      import pandas as pd
      df = pd.read_excel("三年級總成績單.xlsx")
      for i in df['班級'].unique():
      df[df['班級']==i].to_excel(
      "三年級總成績單.xlsx",index=False,sheet_name=f"{i}"
      )
      

      但是執行後發現每次生成的工作表都會覆蓋前一個,最終只剩下一個表,用這個方法實現

      import pandas as pd
      df = pd.read_excel('三年級總成績單.xlsx')
      writer = pd.ExcekWriter("三年級總成績單.xlsx")
      df.to_excel(writer,sheet_name='總成績',index=False)
      for j in df['班級'].unique():
      df[df['班級']==j].to_excel(writer,sheet_name=j,index=False)
      

      ExcelWriter()方法,他會幫助我們建立一個空的容器對象writer

  • 批量將不同的工作表合並到一個excel文件

    import pandas as pd
    sheet_names = pd.ExcelFile("三年級分班成績單.xlsx").sheet_names
    df_all = pd.DataFrame()
    for i in sheet_names:
    df = pd.read_excel("三年級分班成績單.xlsx",sheet_name=i)
    df_all = df_all.append(df)
    df_all.to_excel(
    '三年級分班成績單.xlsx',sheet_name='總成績'
    )
    

    ExcelFile()會得到一個ExcelFile對象。該對象有一個很好用的sheet_names屬性,它能夠獲取當前表格中所有工作表的名稱,並以一個列表返回


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved