Pandas快速入門

寫在前面

上一篇文章中,我寫的是Numpy快速入門, 這次寫一下Pandas的快速入門,這篇博客同樣是針對想入門機器學習和深度學習,或者數據分析的小白而寫,我們都知道機器學習和深度學習,數據分析的編程基礎就是Python編程,而最常用的一些庫,像numpy,pandas,matplotlib,sklearn等這些庫都必須熟記於心。

依然是強調快速上手的學習技能: 掌握一些基本概念,建立一個知識框架,然後就去實戰,在實戰中學習新知識,來填充這個框架。具體的學習方法:見我寫過的另一篇博客: 在人工智能時代,如何快速學習

所以如果想入門人工智能或者數據分析,千萬不要想着我Python學一遍,各種庫先學一遍這樣,不僅慢,有時候還會浪費很多時間,所以我根據之前整理的一些pandas知識,總結了一個pandas的快速入門(後續還有matplotlib的)有了這些知識,然後去通過項目實戰,然後再補充,應該會快速上手。

如果想更深入的學習pandas,我後面也會給出一些鏈接,是我曾經學習時整理的筆記,希望有所幫助。

什麼是Pandas? 熊貓?

Pandas 可以說是基於 NumPy 構建的含有更高級數據結構和分析能力的工具包, 實現了類似Excel表的功能,可以對二維數據表進行很方便的操作。

在數據分析工作中,Pandas 的使用頻率是很高的,一方面是因爲 Pandas 提供的基礎數據結構 DataFrame 與 json 的契合度很高,轉換起來就很方便。另一方面,如果我們日常的數據清理工作不是很複雜的話,你通常用幾句 Pandas 代碼就可以對數據進行規整。

Pandas的核心數據結構:Series 和 DataFrame 這兩個核心數據結構。他們分別代表着一維的序列和二維的表結構。基於這兩種數據結構,Pandas 可以對數據進行導入、清洗、處理、統計和輸出。

快速掌握Pandas,就要快速學會這兩種核心數據結構。

Series

Series 是個定長的字典序列。說是定長是因爲在存儲的時候,相當於兩個 ndarray,這也是和字典結構最大的不同。因爲在字典的結構裏,元素的個數是不固定的。

Series 有兩個基本屬性:index 和 values。在 Series 結構中,index 默認是 0,1,2,……遞增的整數序列,當然我們也可以自己來指定索引,比如 index=[‘a’, ‘b’, ‘c’, ‘d’]。

import pandas as pd
from pandas import Series, DataFrame
x1 = Series([1,2,3,4])
x2 = Series(data=[1,2,3,4], index=['a', 'b', 'c', 'd'])
print x1
print x2

上面這個例子中,x1 中的 index 採用的是默認值,x2 中 index 進行了指定。我們也可以採用字典的方式來創建 Series,比如:

d = {'a':1, 'b':2, 'c':3, 'd':4}
x3 = Series(d)
print x3 

DataFrame

DataFrame 類型數據結構類似數據庫表。它包括了行索引和列索引,我們可以將 DataFrame 看成是由相同索引的 Series 組成的字典類型。

import pandas as pd
from pandas import Series, DataFrame
data = {'Chinese': [66, 95, 93, 90,80],'English': [65, 85, 92, 88, 90],'Math': [30, 98, 96, 77, 90]}
df1= DataFrame(data)
df2 = DataFrame(data, index=['ZhangFei', 'GuanYu', 'ZhaoYun', 'HuangZhong', 'DianWei'], columns=['English', 'Math', 'Chinese'])
print df1
print df2

在後面的案例中,我一般會用 df, df1, df2 這些作爲 DataFrame 數據類型的變量名,我們以例子中的 df2 爲例,列索引是[‘English’, ‘Math’, ‘Chinese’],行索引是[‘ZhangFei’, ‘GuanYu’, ‘ZhaoYun’, ‘HuangZhong’, ‘DianWei’],所以 df2 的輸出是:


            English  Math  Chinese
ZhangFei         65    30       66
GuanYu           85    98       95
ZhaoYun          92    96       93
HuangZhong       88    77       90
DianWei          90    90       80

基本操作

數據的導入與輸出

Pandas 允許直接從 xlsx,csv 等文件中導入數據,也可以輸出到 xlsx, csv 等文件,非常方便。
需要說明的是,在運行的過程可能會存在缺少 xlrd 和 openpyxl 包的情況,到時候如果缺少了,可以在命令行模式下使用“pip install”命令來進行安裝。

import pandas as pd
from pandas import Series, DataFrame
score = DataFrame(pd.read_excel('data.xlsx'))
score.to_excel('data1.xlsx')
print score

數據清洗

數據清洗是數據準備過程中必不可少的環節,Pandas 也爲我們提供了數據清洗的工具,在後面數據清洗的章節中會給你做詳細的介紹,這裏簡單介紹下 Pandas 在數據清洗中的使用方法。

刪除 DataFrame 中的不必要的列或行

Pandas 提供了一個便捷的方法 drop() 函數來刪除我們不想要的列或行

df2 = df2.drop(columns=['Chinese'])

想把“張飛”這行刪掉。

df2 = df2.drop(index=['ZhangFei'])
重命名列名 columns,讓列表名更容易識別

如果你想對 DataFrame 中的 columns 進行重命名,可以直接使用 rename(columns=new_names, inplace=True) 函數,比如我把列名 Chinese 改成 YuWen,English 改成 YingYu。

df2.rename(columns={'Chinese': 'YuWen', 'English': 'Yingyu'}, inplace = True)
去重複的值

數據採集可能存在重複的行,這時只要使用 drop_duplicates() 就會自動把重複的行去掉

df = df.drop_duplicates() #去除重複行
格式問題
  • 更改數據格式
    這是個比較常用的操作,因爲很多時候數據格式不規範,我們可以使用 astype 函數來規範數據格式,比如我們把 Chinese 字段的值改成 str 類型,或者 int64 可以這麼寫
df2['Chinese'].astype('str') 
df2['Chinese'].astype(np.int64) 
  • 數據間的空格
    有時候我們先把格式轉成了 str 類型,是爲了方便對數據進行操作,這時想要刪除數據間的空格,我們就可以使用 strip 函數:
#刪除左右兩邊空格
df2['Chinese']=df2['Chinese'].map(str.strip)
#刪除左邊空格
df2['Chinese']=df2['Chinese'].map(str.lstrip)
#刪除右邊空格
df2['Chinese']=df2['Chinese'].map(str.rstrip)

如果數據裏有某個特殊的符號,我們想要刪除怎麼辦?同樣可以使用 strip 函數,比如 Chinese 字段裏有美元符號,我們想把這個刪掉,可以這麼寫:

df2['Chinese']=df2['Chinese'].str.strip('$')
大小寫轉換

大小寫是個比較常見的操作,比如人名、城市名等的統一都可能用到大小寫的轉換,在 Python 裏直接使用 upper(), lower(), title() 函數,方法如下:

#全部大寫
df2.columns = df2.columns.str.upper()
#全部小寫
df2.columns = df2.columns.str.lower()
#首字母大寫
df2.columns = df2.columns.str.title()
查找空值

數據量大的情況下,有些字段存在空值 NaN 的可能,這時就需要使用 Pandas 中的 isnull 函數進行查找。比如,我們輸入一個數據表如下:
在這裏插入圖片描述
如果我們想看下哪個地方存在空值 NaN,可以針對數據表 df 進行 df.isnull(),結果如下:
在這裏插入圖片描述
如果我想知道哪列存在空值,可以使用 df.isnull().any(),結果如下:
在這裏插入圖片描述

使用apply函數對數據進行清洗

apply 函數是 Pandas 中自由度非常高的函數,使用頻率也非常高。比如我們想對 name 列的數值都進行大寫轉化可以用:

df['name'] = df['name'].apply(str.upper)

我們也可以定義個函數,在 apply 中進行使用。比如定義 double_df 函數是將原來的數值 *2 進行返回。然後對 df1 中的“語文”列的數值進行 *2 處理,可以寫成:

def double_df(x):
           return 2*x
df1[u'語文'] = df1[u'語文'].apply(double_df)

我們也可以定義更復雜的函數,比如對於 DataFrame,我們新增兩列,其中’new1’列是“語文”和“英語”成績之和的 m 倍,'new2’列是“語文”和“英語”成績之和的 n 倍,我們可以這樣寫:

def plus(df,n,m):
    df['new1'] = (df[u'語文']+df[u'英語']) * m
    df['new2'] = (df[u'語文']+df[u'英語']) * n
    return df
df1 = df1.apply(plus,axis=1,args=(2,3,))

數據統計

在數據清洗後,我們就要對數據進行統計了。Pandas 和 NumPy 一樣,都有常用的統計函數,如果遇到空值 NaN,會自動排除。常用的統計函數包括:
在這裏插入圖片描述
表格中有一個 describe() 函數,統計函數千千萬,describe() 函數最簡便。它是個統計大禮包,可以快速讓我們對數據有個全面的瞭解。下面我直接使用 df1.descirbe() 輸出結果爲:

df1 = DataFrame({'name':['ZhangFei', 'GuanYu', 'a', 'b', 'c'], 'data1':range(5)})
print df1.describe()

在這裏插入圖片描述

數據表合併

有時候我們需要將多個渠道源的多個數據表進行合併,一個 DataFrame 相當於一個數據庫的數據表,那麼多個 DataFrame 數據表的合併就相當於多個數據庫的表合併。
比如我要創建兩個 DataFrame:

df1 = DataFrame({'name':['ZhangFei', 'GuanYu', 'a', 'b', 'c'], 'data1':range(5)})
df2 = DataFrame({'name':['ZhangFei', 'GuanYu', 'A', 'B', 'C'], 'data2':range(5)})

兩個 DataFrame 數據表的合併使用的是 merge() 函數,有下面 5 種形式:

  1. 基於指定列進行連接
    比如我們可以基於 name 這列進行連接。
df3 = pd.merge(df1, df2, on='name')

在這裏插入圖片描述
2. inner內連接
inner 內鏈接是 merge 合併的默認情況,inner 內連接其實也就是鍵的交集,在這裏 df1, df2 相同的鍵是 name,所以是基於 name 字段做的連接:

df3 = pd.merge(df1, df2, how='inner')

在這裏插入圖片描述
3. left左連接
左連接是以第一個 DataFrame 爲主進行的連接,第二個 DataFrame 作爲補充。

df3 = pd.merge(df1, df2, how='left')
  1. right右連接
    右連接是以第二個 DataFrame 爲主進行的連接,第一個 DataFrame 作爲補充。
df3 = pd.merge(df1, df2, how='right')

在這裏插入圖片描述
5. outer外連接
外連接相當於求兩個 DataFrame 的並集。

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

在這裏插入圖片描述

如何用SQL方式打開Pandas

Pandas 的 DataFrame 數據類型可以讓我們像處理數據表一樣進行操作,比如數據表的增刪改查,都可以用 Pandas 工具來完成。不過也會有很多人記不住這些 Pandas 的命令,相比之下還是用 SQL 語句更熟練,用 SQL 對數據表進行操作是最方便的,它的語句描述形式更接近我們的自然語言。

事實上,在 Python 裏可以直接使用 SQL 語句來操作 Pandas。

這裏給你介紹個工具:pandasql。

pandasql 中的主要函數是 sqldf,它接收兩個參數:一個 SQL 查詢語句,還有一組環境變量 globals() 或 locals()。這樣我們就可以在 Python 裏,直接用 SQL 語句中對 DataFrame 進行操作,舉個例子:

import pandas as pd
from pandas import DataFrame
from pandasql import sqldf, load_meat, load_births
df1 = DataFrame({'name':['ZhangFei', 'GuanYu', 'a', 'b', 'c'], 'data1':range(5)})
pysqldf = lambda sql: sqldf(sql, globals())
sql = "select * from df1 where name ='ZhangFei'"
print pysqldf(sql)

運行結果

   data1      name
0      0  ZhangFei

上面代碼中,定義了:

pysqldf = lambda sql: sqldf(sql, globals())

在這個例子裏,輸入的參數是 sql,返回的結果是 sqldf 對 sql 的運行結果,當然 sqldf 中也輸入了 globals 全局參數,因爲在 sql 中有對全局參數 df1 的使用。

總結

在這裏插入圖片描述

參考

發佈了78 篇原創文章 · 獲贊 83 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章