1. 程式人生 > >機器學習之路--Pandas

機器學習之路--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