為了更好地掌握數(shù)據(jù)科學必備庫Pandas的基本使用,本文通過精靈寶可夢的數(shù)據(jù)集實戰(zhàn),我們一起過一遍Pandas的基本操作,文中的代碼都附有注釋,并給出了結(jié)果的配圖。
話不多說,我們開始吧!
- 導入pandas庫,并讀取csv文件
import pandas as pd
df=pd.read_csv('pokemon/Pokemon.csv')
- 查看DataFrame信息
df.info() # 數(shù)據(jù)類型,內(nèi)存消耗等信息
df.describe() # 統(tǒng)計特征,均值方差等
- 查看DataFrame的前幾行以及后幾行
pd.head(n=5) # 可以添加參數(shù)n,表示顯示幾行
pd.tail()
- 顯示行列信息
df.index # 列索引
df.columns # 行索引
df.values # array對象
df.dtypes # 列元素屬性
- 刪除行列
df.drop(['#'],axis=1,inplace=True)
# 刪除‘#’列數(shù)據(jù),在原DataFrame上改變
df.drop([1,2,3],axis=0)
# 刪除行索引為1、2、3的行,不在原DataFrame上改變
- 修改列名(兩種方法將‘Type 1’以及‘Type 2’中間的空格去掉)
df.rename(columns={'Type 1':'Type1','Type 2':'Type2'})
df.columns=df.columns.str.replace(' ','')
- 數(shù)據(jù)觀察
df['Defense'].mean() # 所有寶可夢Defense的均值
df['Attack'].argmax() # Attack最高的行索引
df['Sp.Atk'].idxmax() # Sp.Atk最高的行索引
df.sort_values('HP',ascending=False).head(3)
# HP最多的前三條數(shù)據(jù)
df['Type1'].unique() # Type1一共有哪些種類
df['Type1'].nunique() # Type1一共有幾種
df['Type2'].value_counts()
# Type2每種共有多少條
- 檢測空值
df.isnull().sum().sort_values(ascending=False)
# 將空值判斷進行匯總,按從高到低排序
- 空值填充
df['Type2'].fillna(value="Unknown",inplace=True)
# 將所有空缺值填為Unknown
df['Type2'].fillna(df['Type1'], inplace=True)
# 將所有Type2空缺值填為其對應(yīng)Type1的值
- 刪除空值
df.dropna(how='any')
# 去除所有包含空值的行
- 去重
df.drop_duplicates(['Type1'],keep='first')
# 去除相同的Type1的數(shù)據(jù),僅保留第一個
- 數(shù)據(jù)條件查詢
df[df['Name']=='Squirtle']
# 查看杰尼龜?shù)臄?shù)據(jù)
df[df['Type1'].isin(['Fire'])]
# 查看所有Type1為Fire的數(shù)據(jù)
df[(df['Generation']==1)&(df['Attack’]>=100)]
# 查看Generation為1并且攻擊力大于100的寶可夢
- 數(shù)據(jù)訪問方式(單行索引)
df.loc[3] # 訪問行索引為3的數(shù)據(jù)
df.iloc[3] # 訪問第4行數(shù)據(jù),兩行代碼結(jié)果相同
- 數(shù)據(jù)訪問方式(區(qū)域索引,先行后列)
df.iloc[:5,:2] # 數(shù)據(jù)前5行前兩列,按位置索引
df.loc[10:15,['Generation','Attack','Sp.Atk']]
# 數(shù)據(jù)行標簽10-15,列標簽Generation,Attack和Sp.Atk,按標簽索引
df.loc[[10,11,12,13,14,15],['Generation','Attack','Sp.Atk']]
# 與上述寫法結(jié)果相同
df.loc[(df['Legendary']==True)|(df['Type1']=='Grass')]
# Legendary為真或者Type1為Grass的數(shù)據(jù)
- 參考資料:Pandas官方文檔
接下來我們主要涉及seaborn以及matplotlib兩個可視化庫。
上半篇我們主要使用matplotlib來進行柱狀圖、散點圖、餅圖折線圖等的繪制,下半篇主要使用seaborn來進行箱線圖、小提琴圖、分簇散點圖、熱力圖等的繪制。本文是下半篇,上半篇鏈接在這里。
箱線圖
箱線圖可以提供數(shù)據(jù)位置及其分散情況的關(guān)鍵信息,主要用于反映原始數(shù)據(jù)分布的特征,還可以進行多組數(shù)據(jù)分布特征的比較。
如上圖所示,箱線圖主要包含幾個關(guān)鍵的數(shù)據(jù),上、下四方位數(shù),中位數(shù),上、下邊緣以及異常值。簡單來說,上四分位數(shù)表示全部數(shù)據(jù)中有四分之一的數(shù)據(jù)大于它,異常值表示遠離上或下四分位數(shù)。
我們來用箱線圖觀察一下寶可夢的各項屬性的分散情況。
df2=df.drop(['Generation','Total','Legendary'],axis=1)
sns.boxplot(data=df2)
plt.show()
可以看到每種屬性都有異常值,遠超于普通寶可夢,其中血量值的異常值數(shù)量最多。
接著我們來看不同的代目的各種屬性的分布特征,共用同一個Y軸,同時繪制四張子圖。
fig,axes=plt.subplots(1,4,sharey=True)
sns.boxplot(x="Generation",y="Attack",data=df,ax=axes[0])
sns.boxplot(x="Generation",y="Sp.Atk",data=df,ax=axes[1])
sns.boxplot(x="Generation",y="Defense",data=df,ax=axes[2])
sns.boxplot(x="Generation",y="Sp.Def",data=df,ax=axes[3])
fig.set_size_inches(20,7)
總體來看,五代目寶可夢的攻擊力水平要高于其他代目,二代目寶可夢的特殊攻擊水平要低于其他代目。
我們還可以用箱線圖來觀察不同類型的寶可夢對其防御數(shù)值的影響,結(jié)果顯而易見,鋼鐵類型的寶可夢擁有最為卓越的防御屬性。
plt.subplots(figsize=(20,5))
plt.title('Defence by Type 1')
sns.boxplot(x='Type1',y='Defense',data=df2)
plt.ylim(0,240) # 設(shè)置y軸的范圍
plt.show()
另外我們還可以在boxplot中添加參數(shù)hue,分門別類地進行箱線圖繪制,這里根據(jù)是否為神獸來做區(qū)分,顯然神獸的防御屬性遠超非神獸。
小提琴圖
小提琴圖結(jié)合了箱線圖與核密度估計圖的特點,它表征了在一個或多個分類變量情況下,連續(xù)變量數(shù)據(jù)的分布并進行了比較,它是一種觀察多個數(shù)據(jù)分布有效方法。
這里我們繪制不同類型的寶可夢的攻擊力值小提琴圖。
plt.title('Attack by Type1')
sns.violinplot(x="Type1", y ="Attack",data=df2)
plt.ylim(0,200)
plt.show()
小提琴圖中寬度較厚的部分表示具有較高密度點的區(qū)域,而較薄的部分則表示低密度點的區(qū)域。我們可以清楚地看到有一部分電系寶可夢的攻擊力在60左右,小提琴圖有明顯的膨脹部分;而巖石系的寶可夢的攻擊力分布較為平均,小提琴圖呈長窄形狀。
我們對不同代目的寶可夢繪制了總屬性值的小提琴圖,并且將是否為神獸區(qū)分開來。
plt.title('Strongest Generation')
sns.violinplot(x="Generation",y="Total",data=df,hue="Legendary",split=True)
plt.show()
根據(jù)小提琴圖我們似乎可以得出一代目的神獸實力最為強勁,三代目的非神獸實力則更優(yōu)。
熱力圖
這里采用熱力圖來可視化數(shù)據(jù)各列之間的相關(guān)性。可以看到特殊攻擊、攻擊和特殊防御的數(shù)值與是否為神獸的相關(guān)性較高,而代目與其他數(shù)據(jù)的相關(guān)性較低。
df3=df.drop(['Total'],axis=1)
sns.heatmap(df3.corr(),annot=True)
plt.show()
分簇散點圖
分簇散點圖可以理解為數(shù)據(jù)點不重疊的分類散點圖,swarmplot函數(shù)類似于stripplot函數(shù),但該函數(shù)可以對點進行一些調(diào)整,使得數(shù)據(jù)點不重疊。
swarmplot()可以自己實現(xiàn)對數(shù)據(jù)分類的展現(xiàn),也可以作為箱線圖、小提琴圖的一種補充,用來顯示所有結(jié)果以及基本分布情況。
首先通過melt將寶可夢的各項數(shù)據(jù)匯到同一列中,即把窄寬的數(shù)據(jù)拉伸為長瘦型,將寶可夢的各項數(shù)值按照類型以分簇散點圖的形式展現(xiàn)出來。
df5=pd.melt(df2, id_vars=["Name", "Type1", "Type2"], var_name="Stat")
sns.swarmplot(x="Stat", y="value", data=df5, hue="Type1",dodge=True)
plt.legend(bbox_to_anchor=(1, 1), loc=2, borderaxespad=0.)
plt.show()
參考資料
- Visualizing Pokémon Stats with Seaborn
- Seaborn官方文檔






