python資料分析基礎——numpy和matplotlib
numpy庫是python的一個著名的科學計算庫,本文是一個quickstart。
引入:計算BMI
BMI = 體重(kg)/身高(m)^2
假如有如下幾組體重和身高資料,讓求每組資料的BMI值:
weight = [65.4,59.2,63.6,88.4,68.7]
height = [1.73,1.68,1.71,1.89,1.79]
print weight / height ** 2
執行上面程式碼,報錯:TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
這是因為普通的除法是元素級的而非向量級的,並不能應用到一組資料上。
解決方案:使用numpy.ndarray資料結構(N維陣列),運算是面向矩陣的:
import numpy as np np_weight = np.array(weight) np_height = np.array(height) print type(np_weight) print type(np_height) <type 'numpy.ndarray'> <type 'numpy.ndarray'> print np_weight print np_height [ 65.4 59.2 63.6 88.4 68.7] [ 1.73 1.68 1.71 1.89 1.79]
注:和python的列表不同的是,numpy.ndarray資料結構的元素之間是沒有逗號分隔的。
np_bmi = np_weight / np_height ** 2 print type(np_bmi) print np_bmi <type 'numpy.ndarray'> [ 21.85171573 20.97505669 21.75028214 24.7473475 21.44127836]
numpy陣列:numpy.ndarray
numpy.ndarray是numpy最基本的資料結構,即N維陣列,且陣列中的元素需要是同一種類型,如果不是,則會自動轉換成同一種類型,如:
print np.array([1.0,'hi',True])
['1.0' 'hi' 'True']
可以看到都被轉成了字串型別。
不同資料型別的不同行為
# 普通的python列表
py_list = [1,2,3]
# numpy陣列
np_array = np.array(py_list)
print py_list + py_list # 這是列表的拼接
[1, 2, 3, 1, 2, 3]
print np_array + np_array # 這是每兩個對應元素之間的運算
[2 4 6]
子集
print np_bmi[0]
21.8517157272
print np_bmi > 23
[False False False True False]
print np_bmi[np_bmi > 23]
[ 24.7473475]
二維numpy陣列
二維numpy陣列是以list作為元素的陣列,比如:
np_2d = np.array([height,weight])
print type(np_2d)
<type 'numpy.ndarray'>
print np_2d
[[ 1.73 1.68 1.71 1.89 1.79]
[ 65.4 59.2 63.6 88.4 68.7 ]]
print np_2d.shape
(2, 5)
通過shape屬性值可以看出,np_2d是一個2行5列的二維陣列。
single type原則
print np.array([[1,2],[3,'4']])
[['1' '2']
['3' '4']]
二維numpy陣列的子集
np_2d = np.array([height,weight])
print np_2d
[[ 1.73 1.68 1.71 1.89 1.79]
[ 65.4 59.2 63.6 88.4 68.7 ]]
print np_2d[0][2]
1.71
print np_2d[0,2]
1.71
還可以在兩個軸向上分別切片:
print np_2d[:,1:3]
[[ 1.68 1.71]
[ 59.2 63.6 ]]
選取第1行:
print np_2d[1,:]
[ 65.4 59.2 63.6 88.4 68.7]
求對應的BMI值:
print np_2d[1,:] / np_2d[0,:] ** 2
[ 21.85171573 20.97505669 21.75028214 24.7473475 21.44127836]
應用
用numpy生成呈正太分佈的隨機測試資料,並求各項基本的統計資料。
比如生成10000條資料集,記錄的是某個鎮上所有居民的身高(m)、體重(kg)資料,所用到的函式:
np.random.normal(均值,標準差,取樣數)
height = np.random.normal(1.75,0.20,10000)
weight = np.random.normal(60.32,15,10000)
下面將若干個(這裡是2個)一維陣列拼成一個二維陣列(有點像zip()函式的作用):
np_info = np.column_stack((height,weight))
print np_info
[[ 1.88474198 76.24957048]
[ 1.85353302 64.62674488]
[ 1.74999035 67.5831439 ]
...,
[ 1.78187257 50.11001273]
[ 1.90415778 50.65985964]
[ 1.51573081 41.00493358]]
求np_info身高平均值:
print np.mean(np_info[:,0])
1.75460102053
求身高的中位數:
print np.median(np_info[:,0])
1.75385473036
求身高和體重的相關係數:
print np.corrcoef(np_info[:,0],np_info[:,1])
[[ 1.00000000e+00 -1.50825116e-04]
[ -1.50825116e-04 1.00000000e+00]]
求身高的標準差:
print np.std(np_info[:,0])
0.201152169706
排序(不會影響源陣列):
print np.sort(np_info[0:10,0])
[ 1.46053123 1.59268772 1.74939538 1.74999035 1.78229515 1.85353302
1.88474198 1.99755291 2.12384833 2.3727505 ]
求和:
print np.sum(np_info[0:10,0])
18.5673265584
matplotlib庫
基本用法
import numpy as np
import matplotlib.pyplot as plt
# 年份
year = [1950,1970,1990,2010]
# 全球總人口(單位:10億)
pop = [2.519,3.692,5.263,6.972]
# 畫折線圖
plt.plot(year,pop) # year:x軸,pop:y軸
# 顯示出折線圖
plt.show()
畫散點圖
plt.scatter(year,pop)
plt.show()
畫直方圖
# 資料樣本為1000個身高的正態模擬資料
values = np.round(np.random.normal(1.75,0.20,1000),2)
# bins表示直方圖劃分的區間數
plt.hist(values,bins = 10)
plt.show()
圖表個性化
pop = [1.0,1.262,1.650] + pop
year = [1800,1850,1900] + year
# 設定圖表標題
plt.title('World Polulation')
# x,y軸名稱
plt.xlabel('Year')
plt.ylabel('Polulation')
# y軸刻度,第二個引數為顯示的刻度
plt.yticks([0,2,4,6,8,10],['0','2B','4B','6B','8B','10B'])
# 填充曲線下方區域
plt.fill_between(year,pop,0,color = 'green')
plt.show()
解決繪圖時中文顯示為方塊的問題
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定預設字型
plt.rcParams['axes.unicode-minus'] = False # 解決負號顯示為方塊的問題
原文連結:
https://www.cnblogs.com/jiayongji/p/7354213.html
-END-