資料科學 IPython 筆記本 9.6 聚合:最小、最大和之間的任何東西
9.6 聚合:最小、最大和之間的任何東西
本節是《Python 資料科學手冊》(Python Data Science Handbook)的摘錄。
譯者:飛龍
通常,當面對大量資料時,第一步是計算相關資料的彙總統計資訊。也許最常見的彙總統計資料是均值和標準差,它允許你彙總資料集中的“典型”值,但其他彙總也很有用(總和,乘積,中位數,最小值和最大值,分位數等)。
NumPy 具有內建的快速的聚合函式,可用於處理陣列;我們將在這裡討論和演示其中的一些內容。
對陣列中的值求和
作為一個簡單的例子,考慮計算陣列中所有值的總和。Python 本身可以使用內建的sum
import numpy as np
L = np.random.random(100)
sum(L)
# 55.61209116604941
NumPy 的sum
函式的語法非常相似,結果在最簡單的情況下是相同的:
np.sum(L)
# 55.612091166049424
但是,因為它在編譯程式碼中執行操作,所以操作的 NumPy 版本計算速度更快:
big_array = np.random.rand(1000000)
%timeit sum(big_array)
%timeit np.sum(big_array)
'''
10 loops, best of 3: 104 ms per loop
1000 loops, best of 3: 442 μs per loop
'''
但要小心:sum
函式和np.sum
函式不相同,有時會產生混亂!特別是,它們的可選引數具有不同的含義,並且np.sum
知道多個數組維度,我們將在下一節中看到。
最小和最大
類似地,Python 內建了min
和max
函式,用於查詢任何給定陣列的最小值和最大值:
min(big_array), max(big_array)
# (1.1717128136634614e-06, 0.9999976784968716)
NumPy 的相應函式具有相似的語法,並且同樣執行得更快:
np.min(big_array), np.max(big_array)
# (1.1717128136634614e-06, 0.9999976784968716)
%timeit min(big_array)
%timeit np.min(big_array)
'''
10 loops, best of 3: 82.3 ms per loop
1000 loops, best of 3: 497 μs per loop
'''
對於min
,max
,sum
和其他幾個 NumPy 聚合,更短的語法是使用陣列物件本身的方法:
print(big_array.min(), big_array.max(), big_array.sum())
# 1.17171281366e-06 0.999997678497 499911.628197
只要有可能,請確保在 NumPy 陣列上執行時,使用這些聚合的 NumPy 版本!
多維聚合
一種常見型別的聚合操作是沿行或列的聚合。假設你有一些儲存在二維陣列中的資料:
M = np.random.random((3, 4))
print(M)
'''
[[ 0.8967576 0.03783739 0.75952519 0.06682827]
[ 0.8354065 0.99196818 0.19544769 0.43447084]
[ 0.66859307 0.15038721 0.37911423 0.6687194 ]]
'''
預設情況下,每個NumPy聚合函式都將返回整個陣列的聚合:
M.sum()
# 6.0850555667307118
聚合函式接受另一個引數來指定計算聚合的軸。 例如,我們可以通過指定axis = 0
,尋找每列中的最小值:
M.min(axis=0)
# array([ 0.66859307, 0.03783739, 0.19544769, 0.06682827])
該函式返回四個值,對應於四列數字。同樣,我們可以在每行中找到最大值:
M.max(axis=1)
# array([ 0.8967576 , 0.99196818, 0.6687194 ])
此處指定軸的方式,可能會使來自其他語言的使用者感到困惑。axis
關鍵字指定要摺疊的陣列的維度,而不是將返回的維度。
因此,指定axis = 0
意味著摺疊第一個軸:對於二維陣列,這意味著將聚合每列中的值。
其它聚合函式
NumPy 提供了許多其他聚合函式,但我們不會在這裡詳細討論它們。
此外,大多數聚合都有一個NaN
安全的替代品來計算結果,同時忽略缺失值,缺失值由特殊的 IEEE 浮點NaN
值標記(對於缺失資料的更全面討論,請參閱“處理缺失資料)。其中一些NaN
安全的函式直到 NumPy 1.8 才被新增,所以它們在舊的 NumPy 版本中不可用。
下表提供了 NumPy 中可用的實用聚合函式的列表:
函式名稱 | NaN 安全的版本 | 描述 |
---|---|---|
np.sum |
np.nansum |
計算元素的和 |
np.prod |
np.nanprod |
計算元素的積 |
np.mean |
np.nanmean |
計算元素的均值 |
np.std |
np.nanstd |
計算標準差 |
np.var |
np.nanvar |
計算方差 |
np.min |
np.nanmin |
尋找最小值 |
np.max |
np.nanmax |
尋找最大值 |
np.argmin |
np.nanargmin |
尋找最小值的下標 |
np.argmax |
np.nanargmax |
尋找最大值的下標 |
np.median |
np.nanmedian |
計算元素的中值 |
np.percentile |
np.nanpercentile |
計算元素的百分位數 |
np.any |
N/A | 計算是否任何元素是真 |
np.all |
N/A | 計算是否所有元素是真 |
我們將在本書的其餘部分經常看到這些聚合。
示例:美國總統的平均身高是多少?
NumPy 中可用的聚合對於彙總一組值非常有用。舉個簡單的例子,讓我們考慮所有美國總統的身高。此資料位於president_heights.csv
檔案中,該檔案是一個簡單的逗號分隔的標籤和值的列表:
!head -4 data/president_heights.csv
'''
order,name,height(cm)
1,George Washington,189
2,John Adams,170
3,Thomas Jefferson,189
'''
我們將使用 Pandas 軟體包,來讀取檔案並提取資訊(請注意,高度以釐米為單位)。我們將在第三章中更全面地探索 Pandas。
import pandas as pd
data = pd.read_csv('data/president_heights.csv')
heights = np.array(data['height(cm)'])
print(heights)
'''
[189 170 189 163 183 171 185 168 173 183 173 173 175 178 183 193 178 173
174 183 183 168 170 178 182 180 183 178 182 188 175 179 183 193 182 183
177 185 188 188 182 185]
'''
現在我們有了這個資料陣列,我們可以計算各種彙總統計資料:
print("Mean height: ", heights.mean())
print("Standard deviation:", heights.std())
print("Minimum height: ", heights.min())
print("Maximum height: ", heights.max())
'''
Mean height: 179.738095238
Standard deviation: 6.93184344275
Minimum height: 163
Maximum height: 193
'''
請注意,在每種情況下,聚合操作都會將整個陣列縮減為單個彙總值,從而為我們提供值分佈的資訊。
我們也可能打算計算分位數:
print("25th percentile: ", np.percentile(heights, 25))
print("Median: ", np.median(heights))
print("75th percentile: ", np.percentile(heights, 75))
'''
25th percentile: 174.25
Median: 182.0
75th percentile: 183.0
'''
我們看到美國總統的身高中值為 182 釐米,或者只有 6 英尺。
當然,有時看到這些資料的直觀表示更有用,我們可以使用 Matplotlib 中的工具來完成(我們將在第四章中更全面地討論 Matplotlib)。 例如,此程式碼生成以下圖表:
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn; seaborn.set() # 設定繪圖風格
plt.hist(heights)
plt.title('Height Distribution of US Presidents')
plt.xlabel('height (cm)')
plt.ylabel('number');
這些聚合是探索性資料分析的一些基本部分,我們將在本書的後續章節中進行更深入的探索。