機器學習之路--Pandas
Pandas 是對numpy的封裝
Pandas 核心結構DataFrame 近似看出矩陣結構
panda字元型叫object
dataframe其中一行或者一列叫series
dataframe 裡面結構是series series裡面的結構又是ndarryay
series 就是可以自定義索引的ndarray
string index可以用來字串切片
常用程式碼
#匯入模組 import pandas #常用讀取檔案 food_info = pandas.read_csv("food_info.csv") #檔案型別 print(type(food_info)) print(food_info.dtypes) #幫助命令 print (help(pandas.read_csv)) #預設顯示前五行資料 #food_info.head(3) #顯示後四行資料 #food_info.tail(4) #顯示列名 #print (food_info.columns) #顯示行列 print (food_info.shape) #顯示第0行 print (food_info.loc[0]) #顯示第3行到第6行包括第6行 food_info.loc[3:6] #取第2行 第5行 第10行 two_five_ten = [2,5,10] food_info.loc[two_five_ten]#按列名取資料 返回的是一個series結構 這是一種索引加ndarray的結構 ndb_col = food_info["NDB_No"] #按特定列明返回 columns = ["Zinc_(mg)", "Copper_(mg)"] zinc_copper = food_info[columns] #返回列名以列表形式返回 col_names = food_info.columns.tolist() gram_columns = [] #根據特定條件返回值 for c in col_names: if c.endswith("(g)"): gram_columns.append(c) gram_df= food_info[gram_columns] print(gram_df.head(3)) #對每列進行操作 返回值是一個series div_1000 = food_info["Iron_(mg)"] / 1000 add_100 = food_info["Iron_(mg)"] + 100 sub_100 = food_info["Iron_(mg)"] - 100 mult_2 = food_info["Iron_(mg)"]*2 food_info["Water_(g)"] * food_info["Energ_Kcal"] #新建了一列Iron_(g) 並且完成了賦值 food_info["Iron_(g)"] = iron_grams
資料讀取
import pandas csv_info = pandas.read_csv('food_info.csv') print(type(csv_info)) #<class 'pandas.core.frame.DataFrame'> print(csv_info.dtypes) #ps:字元型為object print(csv_info.head()) #視覺化讀入資料,以表格的形式 print(csv_info.head(3)) #視覺化讀入資料,以表格的形式,顯示前3條商品資料 print(csv_info.tail(3)) #視覺化讀入資料,以表格的形式,顯示最後3條商品資料 print(csv_info.columns) #顯示csv表格商品的每個屬性的名稱,以列表的形式 print(csv_info.shape) #顯示讀入資料的規模,即行和列 此例中的值為:(8618, 36)
索引,提取所需資料
import pandas csv_info = pandas.read_csv('food_info.csv') print(csv_info.loc[0]) #第一個商品的所有屬性 資料型別為<class 'pandas.core.series.Series'> print(csv_info.loc[3:6]) #切片操作,取出特定的資料 此資料為第3,4,5,6行的商品資料 print(csv_info.loc[1,3,6]) #切片操作,取出特定的資料 此資料為第1,3,6行的商品資料 columns = ['Lipid_Tot_(g)','Fiber_TD_(g)'] #指定2個屬性 print(csv_info[columns]) #列印這兩列屬性與索引編號 list = csv_info.columns.tolist() #將所有屬性名做成一個列表 a = [] for i in list: if i.endswith("(g)"): #提取出所有以g為單位的屬性,並以劉表的形式表出 a.append(i) b = csv_info[a] #列印b為以g為單位的屬性商品資料
進行加減乘除運算
import pandas csv_info = pandas.read_csv('food_info.csv') div_1000 = csv_info["Iron_(mg)"] / 1000 #單位由mg換為g add_100 = csv_info["Iron_(mg)"] + 100 sub_100 = csv_info["Iron_(mg)"] - 100 mult_2 = csv_info["Iron_(mg)"]*2
新增一列的屬性:(這個屬性由已知屬性計算得出)
import pandas csv_info = pandas.read_csv('food_info.csv') water_energy = csv_info["Water_(g)"] * csv_info["Energ_Kcal"] #新的屬性由兩個已知屬性的乘積得到 iron_grams = csv_info["Iron_(mg)"] / 1000 #進行單位換算 csv_info["Iron_(g)"] = iron_grams #新增新的屬性新增新的一列
找出某一列的最大值
import pandas csv_info = pandas.read_csv('food_info.csv') c = csv_info['Lipid_Tot_(g)'].max() print(c)
對某一屬性進行升序或者降序排序
import pandas csv_info = pandas.read_csv('food_info.csv') csv_info.sort_values("Sodium_(mg)", inplace=True) #進行升序排序,inplace=True表示是新建立記憶體空間 csv_info.sort_values("Sodium_(mg)", inplace=True, ascending=False) #加入aseending=False,表示不按照升序排序,也就是按照降序排序
資料預處理經典案例:泰坦尼克號登船人員資訊
q:年齡缺失的成員有多少人?
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 age = survival['Age'] #提取出age屬性對其操作 age_null = age.isnull() #如果缺失,屬性值為true 如果存在則為false age_nulltrue = age[age_null] #提取出屬性值為true的商品 print(len(age_nulltrue)) #計算出其長度 也就是缺失年齡資料的船員人數
q:為什麼要提取缺失成員並去掉?
a:如果有缺失值,不能對此屬性資料進行運算。例如求平均年齡等(ps:平均年齡求法:mean_age = sum(titanic_survival["Age"]) / len(titanic_survival["Age"]))
q:如何篩選出不是nan的值?
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 age = survival['Age'] #提取出age屬性對其操作 age_null = age.isnull() #如果缺失,屬性值為true 如果存在則為false good_age = survival['Age'][age_null == False] print(good_age)
如果想求平均值,還有一個方法(內建方法,忽略nan值):
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 age = survival['Age'].mean() print(age)
q:對一二三等艙求對應的平均價格怎麼求:(*****)
正常思路:
passenger_classes = [1, 2, 3] fares_by_class = {} for this_class in passenger_classes: pclass_rows = titanic_survival[titanic_survival["Pclass"] == this_class] pclass_fares = pclass_rows["Fare"] fare_for_class = pclass_fares.mean() fares_by_class[this_class] = fare_for_class print fares_by_class
pandas方法:
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 passenger_survival = survival.pivot_table(index="Pclass", values="Fare", aggfunc=np.mean) print(passenger_survival)
各個艙位的獲救概率也可以利用此方法:
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 passenger_survival = survival.pivot_table(index="Pclass", values="Survived", aggfunc=np.mean) print(passenger_survival)
三個碼頭與獲救人數和價格的關係(此時求的是和,不是均值)
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 passenger_survival = survival.pivot_table(index="Embarked", values=["Fare","Survived"], aggfunc=np.sum) print(passenger_survival)
在pivot_table中不寫aggfunc= 預設輸出平均值
刪除一些有nan的行,讓資料都是可處理的
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 drop_na_columns = survival.dropna(axis=1) new_titanic_survival = survival.dropna(axis=0,subset=["Age", "Sex"]) #不要age或者sex裡面為空的資料 print(new_titanic_survival)
通過索引的方法找到具體需要的資料
row_index_83_age = titanic_survival.loc[83,"Age"] row_index_1000_pclass = titanic_survival.loc[766,"Pclass"]
如果要把排序好的index(索引)值也發生相應的改變,變為排序好的
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 new_titanic_survival = survival.sort_values("Age",ascending=False) print(new_titanic_survival[0:10]) itanic_reindexed = new_titanic_survival.reset_index(drop=True) print(survival.iloc[0:10])
自定義函式(將自己編好的函式在物件中實現呼叫)
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 def a(): pass b = survival.apply(a) def not_null_count(column): column_null = pd.isnull(column) null = column[column_null] return len(null) column_null_count = titanic_survival.apply(not_null_count) print column_null_count def which_class(row): pclass = row['Pclass'] if pd.isnull(pclass): return "Unknown" elif pclass == 1: return "First Class" elif pclass == 2: return "Second Class" elif pclass == 3: return "Third Class" classes = titanic_survival.apply(which_class, axis=1) print classes def generate_age_label(row): age = row["Age"] if pd.isnull(age): return "unknown" elif age < 18: return "minor" else: return "adult" age_labels = titanic_survival.apply(generate_age_label, axis=1) print age_labels titanic_survival['age_labels'] = age_labels age_group_survival = titanic_survival.pivot_table(index="age_labels", values="Survived") print age_group_survival
dataframe 是由許多的series組成的,series也就是資料的其中一行或者其中一列
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 series = survival['Name'] print(type(series)) #<class 'pandas.core.series.Series'>
import pandas as pd import numpy as np survival = pd.read_csv('titanic_train.csv') #讀入檔案 series = survival['Name'] a = series.values print(type(a)) #<class 'numpy.ndarray'>
會發現pandas其實是封裝在numpy裡的
用匿名函式求標準差
rt_mt_user = float_df[['RT_user_norm', 'Metacritic_user_nom']] rt_mt_user.apply(lambda x: np.std(x), axis=1)
補充:
1.
pandas中索引的使用
定義一個pandas的DataFrame對像
import pandas as pd
data = pd.DataFrame({'A':[1,2,3],'B':[4,5,6],'C':[7,8,9]},index=["a","b","c"])
data
A B C
a 1 4 7
b 2 5 8
c 3 6 9
.loc 的使用
.loc[],中括號裡面是先行後列,以逗號分割,行和列分別是行標籤和列標籤,比如我要得到數字5,那麼就就是:
data.loc["b","B"]
因為行標籤為b,列標籤為B,同理,那麼4就是data[“a”,”B”]
上面只是選擇某一個值,那麼如果我要選擇一個區域呢,比如我要選擇5,8,6,9,那麼可以這樣做:
data.loc['b':'c','B':'C']
因為選擇的區域,左上角的值是5,右下角的值是9,那麼這個矩形區域的值就是這兩個座標之間,也就是對應5的行標籤到9的行標籤,5的列標籤到9的列標籤,行列標籤之間用逗號隔開,行標籤與行標籤之間,列標籤與列標籤之間用冒號隔開,記住,.loc是用行列標籤來進行選擇資料的。那麼,我們會想,那我們只知道要第幾行,第幾列的資料呢,這該怎麼辦,剛好,.iloc就是幹這個事的
.iloc
.iloc[]與loc一樣,中括號裡面也是先行後列,行列標籤用逗號分割,與loc不同的之處是,.iloc 是根據行數與列數來索引的,比如上面提到的得到數字5,那麼用iloc來表示就是data.iloc[1,1],因為5是第2行第2列,注意索引從0開始的,同理4就是data.iloc[0,1],同樣如果我們需要選擇一個區域,比如我要選擇5,8,6,9,那麼用,iloc來選擇就是
data.iloc[1:3,1:3]
因為5在第二行第二列,9在第三行第三列,注意此處區間前閉後開,所以是1:3,與loc不同的是loc前閉後閉,以及loc是根據行列標籤,而.iloc是根據行數與列數
.ix
.ix我發現,上面兩種用法他都可以,它既可以根據行列標籤又可以根據行列數,比如拿到5
data.ix[1,1]
data.ix["b","B"]
上面兩種做法都可以的,同理選擇一個區域
data.ix[1:3,1:3]
data.ix['b':'c','B':'C']
以上兩種方法都是取到5,6,8,9