學習筆記Python之Pandas
Pandas 資料結構—Series
Pandas Series 類似表格中的一個列(column),類似於一維陣列,可以儲存任何資料型別。
Series由索引(index)和列組成,函式如下:
pandas.Series(data,index,dtype,name,copy)
引數說明
- data:一組資料(ndarray型別)
- index:資料索引標籤,如果不指定,預設從0開始
- dtype:資料型別,預設會自己判斷
- name:設定名稱
- copy:拷貝資料,預設為False
建立一個簡單的Series例項:
import pandas as pd a = [1,2,3] myvar = pd.Series(a)print(myvar)
輸出結果如下:
從上圖可知,如果沒有指定索引,索引值就從0 開始,我們可以根據索引值讀取資料:
import pandas as pd a = [1,2,3] myvar = pd.Series(a) print(myver[1])
輸出結果為:
2
我們可以指定索引值,如下例:
import pandas as pd a = ["Google","Runoob",'Wiki'] myvar = pd.Series(a,index = ["x","y","z"]) print(myvar)
輸出結果如下:
根據索引值讀取資料:
import pandas as pd a= ["Google","Runoob",'Wiki'] myvar = pd.Series(a,index = ["x","y","z"]) print(myvar["y"])
輸出結果如下:
Runoob
我們也可以使用key/value物件,類似字典來建立Series:
import pandas as pd sites = {1:"Google", 2:"Runoob", 3:"Wiki"} myvar = pd.Series(sites) print(myvar)
輸出結果如下:
從上圖可知,字典的key變成了索引值。
如果我們只需要字典的中的一部分資料,只需要指定需要資料的索引即可,如下例項:
import pandas as pd sites = {1:"Google", 2:"Runoob", 3:"Wiki"} myvar = pd.Series(sites,index = [1,2]) print(myvar)
輸出結果如下:
設定Series名稱引數:
import pandas as pd sites = {1:"Google", 2:"Runoob", 3:"Wiki"} myvar = pd.Series(sites,index = [1,2],name = "RUNOOB-Series-TEST") print(myvar)
輸出結果如下:
Pandas資料結構 - DataFrame
DataFrame 是一個表格型的資料結構,它含有一組有序的列,每列可以是不同的值型別(數值、字串、布林型值)。DataFrame既有行索引也有列索引,它可以被看作是由Series組成的字典(共同用一個索引)
DataFrame構造方法如下:
pandas.DataFrame(data,index,columns,dtype,copy)
引數說明:
- data:一組資料(ndarray、series、map、lists、dict等型別)
- index:索引值,或者可以稱為行標籤
- columns:列標籤,預設為RangeIndex(0,1,2,...,n)
- dtype:資料型別
- copy:拷貝資料,預設為False
Pandas DataFrame 是一個二維的陣列結構,類似二維陣列
#使用列表建立 import pandas as pd data = [["Google",10],[“Runoob”,12],["Wiki",13]] df = pd.DataFrame(data,columns = ['Site','Age'],dtype = float) print(df)
輸出結果如下:
以下例項用ndarrays 建立,ndarray 的長度必須相同,如果傳遞了index,則索引的長度應等於陣列的長度,如果沒有傳遞索引,則預設情況下,索引將是range(n),其中n是陣列長度。
#使用ndarrays建立 import pandas as pd data = {'Site':['Google','Runoob','Wiki'],'Age':[10,12,13]}
#這裡陣列指的是['Google','Runoob','Wiki'],[10,12,13]
df = pd.DataFrame(data)
print(df)
輸出結果如下:
由以上輸出結果可知,DataFrame資料型別一個表格,包括rows(行),和columns(列)
還可以使用字典(key/value),其中字典的key為列名:
#使用字典建立 import pandas as pd data = [{'a':1, 'b':2},{'a':5, 'b':10, 'c':20}] df = pd.DataFrame(data) print(df)
輸出結果為
沒有對應的部分資料為NaN
Pandas可以使用loc屬性返回指定行的資料,如果沒有設定索引,第一行索引為0,第二行索引為1,以此類推:
import pandas as pd data = { "calories": [420, 380, 390], "duration": [50, 40, 45] } # 資料載入到 DataFrame 物件 df = pd.DataFrame(data) # 返回第一行 print(df.loc[0]) # 返回第二行 print(df.loc[1])
輸出結果如下:注意:返回結果其實就是一個Pandas Series資料。
#也可以返回多行資料,使用[[...]]格式,...為各行索引
import pandas as pd data = { "calories": [420, 380, 390], "duration": [50, 40, 45] } # 資料載入到 DataFrame 物件 df = pd.DataFrame(data) # 返回第一行和第二行 print(df.loc[[0, 1]])
輸出結果為:注意:返回結果其實就是一個Pandas DataFrame 資料
#我們可以指定索引值,如下例項: import pandas as pd data = { "calories":[420,380,390], "duration":[50,40,45] } df = pd.DataFrame(data, index = ["day1","day2","day3"]) print(df)
輸出結果為:
Pandas可以使用loc屬性返回指定索引對應到某一行:
import pandas as pd data = { "calories":[420,380,390], "duration":[50,40,45] } df = pd.DataFrame(data, index = ["day1","day2","day3"]) #指定索引 print(df.loc["day2"])
輸出結果為:
Pandas CSV檔案
CSV(Comma-Separated Values,逗號分隔值,有時也稱為字元分隔值,因為分隔字元也可以不是逗號),其檔案以純文字形式儲存表格資料(數字和文字)
CSV是一種通用的、相對簡單的檔案格式,被使用者、商業和科學廣泛應用。
Pandas可以很方便的處理CSV檔案。
import pandas as pd df = pd.read_csv("nba.csv") print(df.to_string())
to_string() 用於返回DataFrame型別的資料,如果不使用該函式,則輸出結果為資料的前面5行和末尾5行,中間部分以...代替。使用了to_string相當於全部輸出
import pandas as pd df = pd.read_csv('nba.csv') print(df)
輸出結果為:
我們也可以使用to_csv()方法將DataFrame儲存為csv檔案:
import pandas as pd #三個欄位 name,site,age nme = ["Google","Runoob","Taobao","Wiki"] st = ["www.google.com","www.runoob.com","www.taobao.com","www.wikipedia.org"] ag = [90,40,80,98] #字典 dict = {'name':nme,'site':st,'age':ag} df = pd.DataFrame(dict) #儲存 dataframe df.to_csv('site.csv')
執行成功後,我們開啟site.csv檔案,顯示結果如下:
資料處理
1.head()
head(n)方法用於讀取前面的n行,如果不填引數n,預設返回5行。
import pandas as pd df = pd.read_csv("nba.csv") print(df.head())
輸出結果為:
2.tail()
tail(n)方法用於讀取尾部的n行,如果不填引數n,預設返回5行,空行各個欄位的值返回NaN
import pandas as pd df = pd.read_csv("nba.csv") print(df.tail())
輸出結果為:
3.info()
info()方法返回表格的一些基本資訊:
import pandas as pd df = pd.read_csv("nba.csv") print(df.info())
輸出結果為:
non-null為非空資料,我們可以看到上面的資訊中,總共458行,College欄位的空值最多。
Pandas 資料清洗
資料清洗是對一些沒有用的資料進行處理的過程。
很多資料集存在資料缺失、資料格式錯誤、錯誤資料或重複資料的情況,如果要對使資料分析更加準確,就需要對這些沒有用的資料進行處理。
本文使用到的測試資料如下:
上表包含了四種空資料:
- n/a
- NA
- —
- na
1 Pandas清洗空值
如果我們要刪除包含空欄位的行,可以使用dropna()方法,語法格式如下:
DataFrame.dropna(sxis = 0,how = 'any',thresh = None,subset = None,inplace = False)
引數說明:
- axis:預設為0,表示逢空值剔除整行,如果設定引數 axis = 1表示逢空值去掉整列
- how:預設為'any'如果一行(或一列)裡任何一個數據有出現NA就去掉整行,如何設定how = 'all'一行(或列)都是NA才去掉這整行
- thresh:設定需要多少非空值的資料才可以保留下來的。
- subset:設定想要檢查的列。如果是多個列,可以使用列名的list作為引數
- inplace:如果設定True,將計算得到的值直接覆蓋之前的值並返回None,修改的是源資料。
我們可以通過isnull()判斷各個單元格是否為空。
import pandas as pd df = read_csv("property-data.csv") print(df['NUM_BEDROOMS']) print(df['NUM_BEDROOMS']).isnull()
以上例項輸出結果如下:
以上例子中我們看到Pandas把n/a和NA當作空資料,而認為na不是空資料,不符合我們要求,我們可以指定空資料型別:
import pandas as pd missing_values = ["n/a", "na", "--"] df = read_csv("property-data.csv", na_values = missing_values) print(df['NUM_BEDROOMS']) print(df['NUM_BEDROOMS']).isnull()
以上例項輸出結果如下:
接下來的例項演示了刪除包含空資料的行。
import pandas as pd df = pd.read_csv("property-data.csv") new_df = df.dropna() print(new_df.to_string())
以上例項輸出結果如下:
注意:預設情況下,dropna()方法返回一個新的DataFrame,不會修改源資料。
如果你要修改源資料DataFrame,可以使用inplace = True 引數:
import pandas as pd df = pd.read_csv('property-data.csv') df.dropna(inplace = True) print(df.to_string())
以上例項輸出結果如下:
我們也可以移除指定列有空值的行:
import pandas as pd df = pd.read_csv("property-data.csv") df.dropna(subset = ['ST_NUM'],inplace = True) print(df.to_string())
以上例項輸出結果如下:
我們也可以用fillna()方法來替換一些空欄位:
import pandas as pd df = pd.read_csv("property-data.csv") df.fillna(12345,inplace = True) print(df.to_string())
以上例項輸出結果如下:
我們也可以指定某一個列來替換資料:
import pandas as pd df = pd.read_csv('property-data.csv') df['PID'].fillna(12345, inplace = True)#指定替換PID列的空資料 print(df.to_string())
以上例項輸出結果如下:
替換空單元格的常用方法是計算列的均值、中位數值或眾數。
Pandas使用mean()、median()和mode()方法計算列的均值(所有值加起來的平均值)、中位數值(排序後排在中間的數)和眾數(出現頻率最高的數)。
#使用mean()方法計算列的均值並替換空單元格 import pandas as pd df = pd.read_csv("property-data.csv") x = df["ST_NUM"].mean() #同理可以換成中位數median()、眾數mode() df["ST_NUM"].fillna(x,inplace = True) print(df.to_string())
以上例項輸出結果如下,紅框為計算的均值替換來空單元格:
2 Pandas清洗格式錯誤資料
資料格式錯誤的單元格會使資料分析變得困難,我們可以通過包含空單元格的行,或者將列中的所有單元格轉換為相同格式的資料
以下例項會格式化日期:
import pandas as pd #第三個日期格式錯誤 data = { "Date":['2020/12/01', '2020/12/02', '20201226'] "duration":[50, 40, 45] } df = pd.DataFrame(data, index = ["day1","day2","day3"]) df["Date"] = pd.to_datetime(df["Date"]) print(df.to_string())
以上例項輸出結果如下:
資料錯誤也是很常見的情況,我們可以對錯誤的資料進行替換或者移除。
以下例項會替換錯誤年齡的資料:
import pandas as pd person = { "name":['Google','Runoob','Taobao'], "age":[50,40,12345] #這裡12345 年齡資料是錯誤的 } df = pd.DataFrame(person) df.loc[2,'age'] = 30 #修改資料 print(df.to_string())
以上例項輸出結果如下:
也可以設定條件語句:
#將age大於120的設定為120 import pandas as pd person = { "name":['Google','Runoob','Taobao'], "age":[50,200,12345] } df = pd.DataFrame(person) for x in df.index: if df.loc[x,"age"]>120: df.loc[x,"age"] = 120 print(df.to_string())
以上例項輸出結果如下:
也可以將錯誤的資料的行刪除:
#將age大於120的設定為刪除 import pandas as pd person = { "name":['Google','Runoob','Taobao'], "age":[50,40,12345] } df = pd.DataFrame(person) for x in df.index: if df.loc[x,"age"]>120: df.drop(x,inplace =True) print(df.to_string())
以上例項輸出結果如下:
3 Pandas 清洗重複資料
如果我們要清洗重複資料,可以使用duplicated()和drop_dulicates()方法。
如果對應的資料是重複的,dulicated()會返回True,否則返回False
import pandas as pd person = { "name": ['Google', 'Runoob', 'Runoob', 'Taobao'], "age": [50, 40, 40, 23] df = pd.DataFrame(person) print(df.duplicated())
以上例項輸出結果如下:
刪除重複資料,可以直接使用drop_dulicates()方法。
import pandas as pd person = { "name": ['Google', 'Runoob', 'Runoob', 'Taobao'], "age": [50, 40, 40, 23] df = pd.DataFrame(person) df.drop_duplicates(inplace = True) print(df)
以上例項輸出結果如下: