當前位置: 首頁>>技術教程>>正文


Pandas Matplotlib數據可視化入門教程

本文以數據及代碼示例講解Pandas和Matplotlib的基本用法,主要內容分為以下幾節:

基本要求

  • 從CSV讀取數據
  • 格式化,清理和過濾數據框
  • Group-by和合並

可視化數據

  • Plot函數基礎
  • Seaborn 小提琴圖和lm-plots
  • 配對圖和熱力圖

圖美學

  • 多軸繪圖
  • 使圖表看起來更美觀[藝術]

如果你想學習如何進行數據繪圖或者數據可視化,本文將對您有所幫助。

基本要求

讀取CSV ,需要導入Matplotlib和Pandas

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
%matplotlib inline
car_data = pd.read_csv('inbox/CarData-E-class-Tue Jul 03 2018.csv')

Inline(內聯)表示將圖顯示為單元格輸出(jupyter notebook單元格,而不是單獨窗口),read_csv返回一個DataFrame,文件路徑相對於notebook跟目錄而言。

格式化,清理和過濾數據(DataFrame)

通常,在處理大量特征列時,最好能看一下第一行或所有列的名稱,這可使用colums屬性head(n行)功能。但是,如果我們對諸如modelLine這樣的類別的值感興趣,則可以使用方括號語法訪問列,並使用 .unique() 檢查選項。

print(car_data.columns)
car_data.head(2)
car_data['modelLine'].unique()

我們將使用正則表達式將所有包含SE的東西替換為特殊設備。同時,有一些列含Nans(不是數字),可以dropna(subset = [‘modelLine’])去掉modelLine列中值為Nans行。

car_data = car_data.dropna(subset=['modelLine'])
car_data['modelLine'] = car_data['modelLine'].replace(to_replace={'.*SE.*': 'Standard equipment'}, regex=True)

我們還可以通過將modelLine的行與某個布爾問題進行比較來過濾掉不需要的值,例如“ undefined”。

car_data = car_data[(car_data['modelLine'] != 'undefined')]
car_data['modelLine'].unique()

注意上麵的 Pandas 是如何從不改變任何現有數據的,因此當我們執行任何改變/過濾器時,我們必須手動覆蓋舊數據。盡管這比較費事,但它是一種有效的減少代碼有害副作用和錯誤的方法。

接下來,我們還需要更改firstRegistration字段,通常應將其視為python日期格式,但是為了方便以後在文章中對數據進行回歸建模,我們將其視為數字字段。

考慮到這些數據與汽車登記相關,因此,年份確實是我們需要保留的重要組成部分。因此,將其視為數字字段意味著我們可以應用數字舍入、乘法/除法來創建“注冊年”功能列,如下所示。

car_data['firstRegistration'].head(5)
car_data[‘firstRegistrationYear’] = round((car_data[‘firstRegistration’] / 10000),0)
car_data[‘firstRegistrationYear’] .head(5)

使用Group-by和合並

Group-by可用於根據數據集中的特征列構建行組,以 “ modelLine”類別列。然後,我們可以對各個組執行諸如均值,最小值,最大值,標準差之類的運算,以幫助描述樣本數據。

group_by_modelLine = car_data.groupby(by=['modelLine'])
car_data_avg = group_by_modelLine.mean()
car_data_count = group_by_modelLine.count()

平均數據

計數數據:請注意,這隻是每個模型行的記錄計數

如您所見,已經為每個Model Line計算了每個數字特征的平均值。Group By具有高度的通用性,並且還接受lambda函數以實現更複雜的行/分組標記。

接下來,我們將組裝僅包含相關特征列的DataFrame,以繪製可用性(也就是汽車數量)和每輛汽車平均裝備的圖表。可以通過傳入關鍵字字典來創建此DataFrame,這些關鍵字代表來自我們現有數據的單列或係列的列和值。或者,我們可以通過兩個DataFrame的索引(modelLine)合並它們,並適當地重命名重複列的後綴。

然後,我們將繪製這兩個變量,按設備排序,然後將可用性繪製為水平條形圖。

# Since all the columns in car_data_count are the same, we will use just the first column as the rest yield the same result. iloc allows us to take all the rows and the zeroth column.
car_data_count_series = car_data_count.iloc[:,0]
features_of_interest = pd.DataFrame({'equipment': car_data_avg['equipment'], 'availability': car_data_count_series})
alternative_method = car_data_avg.merge(car_data_count, left_index=True, right_index=True, suffixes=['_avg','_count'])
alternative_method[['equipment_avg', 'firstRegistration_count']].sort_values(by=['equipment_avg', 'firstRegistration_count'], ascending=True).plot(kind='barh')

可視化數據

Pandas Plot函數

Pandas具有內置的.plot()函數作為DataFrame類的一部分。它具有幾個關鍵參數:

kind—繪圖類型,可以在文檔中找到的“ bar”,“ barh”,“ pie”,“ scatter”,“ kde”等。
color—顏色,接受和對應於每個數據係列/列的十六進製代碼數組。
linestyle—線條形狀,“實心”,“虛線”,“虛線”(僅適用於折線圖)
xlim,ylim—指定要為其繪製圖的元組(下限,上限)
legend—用於顯示或隱藏圖例的布爾值
labels—與數據框中的列數相對應的列表,可以在此處為圖例提供描述性名稱
title—plot的字符串標題

這些都比較容易使用,我們將在後麵的文章中使用.plot()給出一些示例。

Seaborn lmplots

Seaborn建立在matplotlib之上,以提供更豐富的現成環境。它包括一個整潔的lmplot繪圖函數,用於快速探索多個變量。使用我們的汽車數據示例,我們想了解汽車的設備kit-out與售價之間的關聯。首先,導入seaborn:

import seaborn as sns

為設備和價格(x和y軸)的輸入列標簽,然後輸入實際的DataFrame來源。使用col關鍵字為Model Line生成一個單獨的圖,並將col_wrap 2設置為一個漂亮的網格。

filtered_class = car_data[car_data['modelLine'] != 'AVANTGARDE']
sns.lmplot("equipment", "price", data=filtered_class, hue="gears", fit_reg=False, col='modelLine', col_wrap=2)

如您所見,我們用3行代碼即可對數據集進行快速分析。

Seaborn小提琴圖

這些圖非常適合處理大型連續數據集,並且可以類似地通過索引進行細分。使用我們的汽車數據集,我們可以對二手車的價格分布有更深入的了解。由於汽車的壽命會顯著影響價格,因此我們將第一個注冊年份作為x軸變量,將價格作為y。然後,我們可以設置顏色以區分各種模型變體。

from matplotlib.ticker import AutoMinorLocator
fig = plt.figure(figsize=(18,6))
LOOKBACK_YEARS = 3
REGISTRATION_YEAR = 2017
filtered_years = car_data[car_data['firstRegistrationYear'] > REGISTRATION_YEAR - LOOKBACK_YEARS]
ax1 = sns.violinplot('firstRegistrationYear', "price", data=filtered_years, hue='modelLine')
ax1.minorticks_on()
ax1.xaxis.set_minor_locator(AutoMinorLocator(2))
ax1.grid(which='minor', axis='x', linewidth=1)

請注意,小提琴繪圖函數會返回圖中的坐標軸。這使我們可以編輯軸的屬性。在這種情況下,我們已設置次要刻度線,並使用AutoMinorLocator在每個主要間隔之間放置1個次要刻度線。

配對圖相關性熱力圖

在具有少量特征(10–15)的數據集中,Seaborn Pairplots可以快速實現對變量之間任何關係的直觀檢查。沿左對角線的圖形表示每個要素的分布,而對角線之外的圖形則顯示變量之間的關係。

sns.pairplot(car_data.loc[:,car_data.dtypes == 'float64'])

同樣,我們可以利用pandas Corr()查找矩陣中每個變量之間的相關性,並使用Seaborn的Heatmap函數(指定標簽和Heatmap顏色範圍)進行繪製。

corr = car_data.loc[:,car_data.dtypes == 'float64'].corr()
sns.heatmap(corr, xticklabels=corr.columns, yticklabels=corr.columns, cmap=sns.diverging_palette(220, 10, as_cmap=True))

結合使用這兩個工具對於快速識別模型的重要特征非常有用。例如,使用熱力圖,我們可以從第一行看到齒輪的數量和首次注冊與價格成正相關,而裏程數則可能與價格成負相關。

圖美學

多軸繪圖

以下是我之前關於中​​國房地產泡沫的文章中的一些數據。我想顯示所有城市的建設數據,然後在一個圖中按城市級別提供後續細分。

讓我們細分一下如何創建這樣的圖:

首先,我們定義圖形的大小以提供足夠的繪圖空間。使用多軸繪圖時,我們定義了可以放置軸的網格。然後,我們使用subplot2grid函數返回期望位置的坐標軸。

fig = plt.figure(figsize = (15,12))
grid_size = (3,2)
hosts_to_fmt = [] # Place A Title On The Figure
fig.text(x=0.8, y=0.95, s='Sources: China National Bureau of Statistics',fontproperties=subtitle_font, horizontalalignment='left',color='#524939')
# Overlay multiple plots onto the same axis, which spans 1 entire column of the figure
large_left_ax = plt.subplot2grid(grid_size, (0,0), colspan=1, rowspan=3)

然後,我們可以通過指定plot函數的ax屬性來繪製到該軸上。請注意,盡管在特定軸上進行了繪製,但使用secondary_y參數意味著將創建一個新的軸實例。這對於以後存儲格式很重要。

# Aggregating to series into single data frame for ease of plotting
construction_statistics = pd.DataFrame({
    'Constructed Floorspace (sq.m, City Avg)':
     china_constructed_units_total,
    'Purchased Units (sq.m, City Avg)':     
     china_under_construction_units_total,
})
construction_statistics.plot(ax=large_left_ax,
    legend=True, color=['b', 'r'], title='All Tiers')
# Second graph overlayed on the secondary y axis
large_left_ax_secondary = china_years_to_construct_existing_pipeline.plot(
    ax=large_left_ax, label='Years of Backlog', linestyle='dotted',
    legend=True, secondary_y=True, color='g')
# Adds the axis for formatting later
hosts_to_fmt.extend([large_left_ax, large_left_ax_secondary])

要按城市層劃分細分,我們再次使用subplot2grid,但這一次更改每個循環的索引,這樣3層圖表就在另一個圖表的下方繪製。

# For each City Tier overlay a series of graphs on an axis on the right hand column
# Its row position determined by its index
for index, tier in enumerate(draw_tiers[0:3]):
    tier_axis = plt.subplot2grid(grid_size, (index,1))

china_constructed_units_tiered[tier].plot(ax=tier_axis,
title=tier, color=’b’, legend=False)

ax1 = china_under_construction_units_tiered[tier].plot(
ax=tier_axis,linestyle=’dashed’, label=’Purchased Units
(sq.m,City Avg)’, title=tier, legend=True, color=’r’)

ax2 =china_property_price_sqmetre_cities_tiered[tier].plot(
ax=tier_axis, linestyle=’dotted’, label=’Yuan / sq.m’,
secondary_y=True, legend=True, color=’black’)

ax2.set_ylim(0,30000)
hosts_to_fmt.extend([ax1,ax2])

好了,現在我們已經生成了正確的布局並繪製了數據:

讓您的圖表看起來更美觀

在上麵的圖表中,我選擇了類似ft.com的樣式。首先,我們需要通過Matplotlib字體管理器導入字體,並為每個類別創建一個字體屬性對象。

import matplotlib.font_manager as fm# Font Imports
heading_font = fm.FontProperties(fname='/Users/hugo/Desktop/Playfair_Display/PlayfairDisplay-Regular.ttf', size=22)
subtitle_font = fm.FontProperties(
fname='/Users/hugo/Library/Fonts/Roboto-Regular.ttf', size=12) # Color Themes
color_bg = '#FEF1E5'
lighter_highlight = '#FAE6E1'
darker_highlight = '#FBEADC'

接下來,我們將定義一個函數,該函數將:

  • 設置圖形背景(使用set_facecolor)
  • 使用指定的標題字體將標題應用於圖形。
  • 調用布局緊湊函數可以更緊湊地利用繪圖空間。

接下來,我們將遍曆圖中的每個軸,並調用以下函數:

  • 禁用除底部刺(軸邊界)以外的所有刺
  • 將軸的背景色設置為略深。
  • 如果存在legend,請禁用legend周圍的白框。
  • 設置每個軸的標題以使用副標題字體。

最後,我們隻需要調用我們創建的formatter函數,並傳入我們的圖形和之前收集的軸即可。

結論

感謝您閱讀本教程,希望它能幫助您入門並使用Pandas和Matplotlib。

參考資料

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/4326.html,未經允許,請勿轉載。