三天搞定python基礎系列第一天內容請進傳送門:三天搞定python基礎-day1
三天搞定python基礎-day2
(需要指出,這版三天搞定python系列有點偏向科學計算,機器學習大數據這塊,從第二天第三天內容就可以看出來)
大綱:幾個python的常用模塊的簡單應用
NumPy:多維數組的有效操作。 高效的數學函數。
Matplotlib:可視化:2D和(最近)3D圖
SciPy:大型庫實現各種數值算法,例如:
- 線性和非線性方程的解
- 優化
- 數值整合
Sympy:符號計算(解析的 Analytical)
Pandas:統計與數據分析(day3)
一、導入模塊
- 可以通過輸入import關鍵字來導入模塊
import numpy
- 或者使用簡稱,即將模塊通過as關鍵字來命名一個簡稱
import numpy as np
- 有時您不必導入整個模塊,就像
from scipy.stats import norm
練習:導入模塊時間,並使用它來獲取計算機運行特定代碼所需的時間。
import timeit def funl (x, y): return x**2 + y**3 t_start = timeit.default_timer() z = funl(109.2, 367.1) t_end = timeit.default_timer() cost = t_end -t_start print ( 'Time cost of funl is %f' %cost)
二、numpy
ndarray類型
- NumPy提供了一種新的數據類型:ndarray(n維數組)。
- 與元組和列表不同,數組只能存儲相同類型的對象(例如只有floats或只有ints)
- 這使得數組上的操作比列表快得多; 此外,陣列佔用的內存少於列表。
- 數組爲列表索引機制提供強大的擴展
import numpy as np
In [1] : np.array([2, 3, 6, 7]) Out[l] : array([2, 3, 6, 7]) In [2] : np.array([2, 3, 6, 7.]) Out [2] : array([ 2., 3., 6., 7.]) <- Hamogenaous
創建均勻間隔的數組
- arange:
in[1]:np.arange(5)
Out [l]:array([0,1,2,3,4])
range(start, stop, step)的所有三個參數即起始值,結束值,步長都是可以用的 另外還有一個數據的dtype參數
np.arange(10,100,20,dtype = float)
array([ 10., 30., 50., 70., 90.])
np.arange(3, dtype=np.uint8)
array([0, 1, 2], dtype=uint8)
- linspace(start,stop,num)返回數字間隔均勻的樣本,按區間[start,stop]計算:
np.linspace(0.,2.5,5)
array([0.,0.625,1.25,1.875,2.5])
這在生成plots圖表中非常有用。
- 註釋:即從0開始,到2.5結束,然後分成5等份
多維數組矩陣 (Matrix by multidimensional array)
In [1] : a = np.array([[1, 2, 3],[4, 5, 6]]) In [2] : a Out [2] : array([[l, 2, 3] ,[4, 5, 6]]) In [3] : a.shape #<- 行、列數等 (Number of rows, columns etc.) Out [3] : (2,3) In [4] : a.ndim #<- 維度數 (Number of dimensions) Out [4] : 2 In [5] : a,size #<- 元素數量 (Total number of elements) Out [5] : 6
形狀變化 (Shape changing)
import numpy as np a = np .arange(0, 20, 1) #1維 b = a.reshape((4, 5)) #4行5列 c = a.reshape((20, 1)) #2維 d = a.reshape((-1, 4)) #-1:自動確定 a.shape =(4, 5) #改變a的形狀
例子
import numpy as np
a = np.array([1,2,3,4,5])
b = a.copy ()
c1 = np.dot(np.transpose(a), b)
print(c1)
c2 = np.dot(a, np.transpose(b))
print(c2)
ax = np.reshape(a, (5,1))
bx = np.reshape(b, (1,5))
c = np.dot(ax, bx)
print(c)
相同的元素填充數組
In [1] : np.zeros(3) # zero(),全0填充數組 Out[l] : array([ O., 0., 0.]) In [2] : np.zeros((2, 2), complex) Out[2] : array([[ 0.+0.j, 0.+0.j], [ 0.+O.j, 0.+0.j]]) In [3] : np.ones((2, 3)) # ones(),全1填充數組 Out[3] : array([[ 1., 1., 1.], [ 1., 1., 1.]])
隨機數字填充數組
- rand: 0和1之間均勻分佈的隨機數
In [1] : np.random.rand(2, 4)
Out[1] : array([[ 0.373767 , 0.24377115, 0.1050342 , 0.16582644] ,
[ 0.31149806, 0.02596055, 0.42367316, 0.67975249l])
- randn: 均值爲0,標準差爲1的標準(高斯)正態分佈 {standard normal (Gaussian) distribution with mean 0 and variance 1}
In [2]: np.random.randn(2, 4)
Out[2]: array([[ O.87747152, 0.39977447, -0.83964985, -1.05129899],
[-1.07933484, 0.49448873, -1.32648606, -0.94193424]])
- 其他標準分佈也可以使用
數組切片(1D) (Array sliciing(1D))
- 以格式start:stop可以用來提取數組的片段(從開始到不包括stop)
In [77]:a = np.array([0,1,2,3,4])
Out[77]:array([0,1,2,3,4])
In [78]:a [1:3] #<--index從0開始 ,所以1是第二個數字,即對應1到3結束,就是到第三個數字,對應是2
Out[78]:array([1,2])
- start可以省略,在這種情況下,它被設置爲零(Notes:貌似留空更合適):
In [79]:a [:3]
Out[79]:array([0,1,2])
- stop也可以省略,在這種情況下它被設置爲數組長度:
In [80]:a [1:]
Out[80]:array([1,2,3,4])
- 也可以使用負指數,具有標準含義:
In [81]:a [1:-1]
Out[81]:array([1,2,3]) # <-- stop爲-1表示倒數第二個數
- 整個數組:a或a [:]
In [77]:a = np.array([0,1,2,3,4])
Out[77]:array([0,1,2,3,4])
- 要獲取,例如每個其他元素,您可以在第二個冒號後面指定第三個數字(步驟(step)):
In [79]:a [::2]
Out[79]:array([0,2,4])
In [80]:a [1:4:2]
Out[80]:array([1,3])
- -1的這個步驟可用於反轉數組:
In [81]:a [::-1]
Out[81]:array([4,3,2,1,0])
數組索引(2D)
- 對於多維數組,索引是整數元組
In [93] : a = np.arange(12) ; a.shape = (3, 4); a
Out[93] : array([[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]])
In [94] : a[1,2]
Out[94] : 6
In [95] : a[1,-1]
Out[95] : 7
數組切片(2D):單行和列
In [96] : a = np.arange(12); a.shape = (3, 4); a
Out[96] : array([[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9,10,11]])
In [97] : a[:,1]
Out[97] : array([1,5,9])
In [98] : a[2,:]
Out[98] : array([ 8, 9, 10, 11])
In [99] : a[1][2]
Out[99] : 6
- 不必明確提供尾隨的冒號:(Trailing colons need not be given explicitly:)
In [100] : a[2]
Out[100] : array([8,9,10,11])
數組索引
>>> a[0,3:5] array( [3,4] ) >>> a[4:,4:] array([[44, 45], [54, 55]]) >>> a[:,2] array([2,12,22,32,42,52]) >>> a[2: :2, ::2] array([[20, 22, 24] [40, 42, 44]])
副本和視圖
- 爲避免修改原始數組,可以製作一個切片的副本
In [30] : a = np.arange(5); a
Out[30] : array([0, 1, 2, 3, 4])
In [31] : b = a[2:].copy(); b
Out[31] : array([2, 3, 4])
In [32] : b[0] = 100
In [33] : b
Out[33] : array([100, 3, 4])
In [34] : a
Out[34] : array([ 0, 1. 2, 3, 4])
矩陣元素乘法
- 運算符 * 表示元素乘法,而不是矩陣乘法:
In [1]: A = np.array([[1, 2],[3, 4]])
In [2]: A
Out[2]: array([[1, 2],
[3, 4]])
In [3]: A * A
Out[3]: array([[1, 4],
[9, 16]])
- 使用dot()函數進行矩陣乘法:
In [4]: np.dot(A, A)
Out[4]: array([[ 7, 10],
[15, 22]])
矩陣乘法
- dot()方法也適用於矩陣向量(matrix-vector)乘法:
In [1]: A
Out[1]: array([[1, 2],[3, 4]])
In [2]: x = np.array([10, 20])
In [3]: np.dot(A, x)
Out[3]: array([ 50, 110])
In [4]: np.dot(x, A)
Out[4]: array([ 70, 100])
將數組保存到文件
- savetxt()將表保存到文本文件。
np.savetxt("myfile.txt", a)
save()將表保存爲Numpy“.npy”格式的二進制文件
np.save("myfile" ,a)
- 生成一個二進制文件myfile .npy,其中包含一個可以使用np.load()加載的文件。
將文本文件讀入數組
loadtxt()將以文本文件存儲的表讀入數組。 (loadtxt() reads a table stored as a text file into an array.)
默認情況下,loadtxt()假定列是用空格分隔的。 您可以通過修改可選的參數進行更改。 以散列(#)開頭的行將被忽略。
示例文本文件data.txt:
|Year| Min temp.| Hax temp.|
|1990| -1.5 | 25.3|
|1991| -3.2| 21.2|
Code:
In [1] : tabla = np.loadtxt("data.txt")
In [2] : table
Out[2] :
array ([[ 1.99000000e+03, -1.50000000e+00, 2.53000000e+01],
[ 1.9910000e+03, -3.2000000e+00, 2.12000000e+01]
Numpy更多高效的功能
Numpy包含許多常用的數學函數,例如:
- np.log
- np.maximum
- np.sin
- np.exp
- np.abs
在大多數情況下,Numpy函數比Math包中的類似函數更有效,特別是對於大規模數據。
三、scipy庫
SciPy的結構
- scipy.integrate - >積分和普通微分方程
- scipy.linalg - >線性代數
- scipy.ndimage - >圖像處理
- scipy.optimize - >優化和根查找(root finding)
- scipy.special - >特殊功能
- scipy.stats - >統計功能
- ...
要加載一個特定的模塊,請這樣使用, 例如 :
- from scipy import linalg
線性代數
- 線性方程的解 (Solution of linear equations:)
import numpy as np
from scipy import linalg
A = np.random.randn(5, 5)
b = np.random.randn(5)
x = linalg.solve(A, b) # A x = b#print(x)
eigen = linalg.eig(A) # eigens#print(eigen)
det = linalg.det(A) # determinant
print(det)
- linalg的其他有用的方法:eig()(特徵值和特徵向量),det()(行列式)。{Other useful functions from linalg: eig() (eigenvalues and eigenvectors), det() (determinant). }
數值整合 (Numerical integration)
- integration.quad是一維積分的自適應數值積分的函數。 (integrate.quad is a function for adaptive numerical quadrature of one-dimensional integrals.)
import numpy as np
from scipy import integrate
def fun(x):
return np.log(x)
value, error = integrate.quad(fun,0,1)
print(value)
print(error)
用Scipy進行統計 (Statistics in Scipy)
- scipy具有用於統計功能的子庫,您可以導入它 (scipy has a sub-library for statistical functions, you can import it by)
from scipy import stats
- 然後您可以使用一些有用的統計功能。 例如,給出標準正態分佈的累積密度函數(Then you are able to use some useful statistical function. For example, the cummulative density function of a standard normal distribution is given like
- 這個包,我們可以直接使用它,如下: (with this package, we can directly use it like)
from scipy import stats
y = stats.norm.cdf(1.2)
優化:數據擬合 (Optimisation: Data fitting)
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def func(x, a, b, c):
return a * np.exp(-b * x) + c
x = np.linspace(0, 4, 50)
y = func(x, 2.5, 1.3, 0.5)
ydata = y+0.2*np.random.normal(size=len(x))
popt, pcov = curve_fit(func, x, ydata)
plt.plot(x, ydata, 'b*')
plt.plot(x, func(x, popt[0], \
popt[1], popt[2]), 'r-')
plt.title('$f(x)=ae^{-bx}+c$ curve fitting')
優化:根搜索 (Optimisation: Root searching)
import numpy as np
from scipy import optimize
def fun(x):
return np.exp(np.exp(x)) - x**2
# 通過初始化點0,找到興趣0 (find zero of fun with initial point 0)
# 通過Newton-Raphson方法 (by Newton-Raphson)
value1 = optimize.newton(fun, 0)
# 通過二分法找到介於(-5,5)之間的 (find zero between (-5,5) by bisection)
value2 = optimize.bisect(fun, -5, 5)
Matplotlib
最簡單的製圖 (The simplest plot)
- 導入庫需要添加以下內容
from matplotlib import pyplot as plt
- 爲了繪製一個函數,我們操作如下 (To plot a function, we do:)
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 201)
#y = x ** 0.5
#plt.plot(x, y) # default plot
plt.figure(figsize = (3, 3)) # new fig
plt.plot(x, x**0.3, 'r--') # red dashed
plt.plot(x, x-1, 'k-') # continue plot
plt.plot(x, np.zeros_like(x), 'k-')
- 注意:您的x軸在plt.plot函數中應與y軸的尺寸相同。 (Note: Your x-axis should be the same dimension to y-axis in plt.plot function.)
多個製圖圖例標籤和標題 (Multiple plotting, legends, labels and title)
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 201)
plt.figure(figsize = (4, 4))
for n in range(2, 5):
y = x ** (1 / n)
plt.plot(x, y, label='x^(1/' \
+ str(n) + ')')
plt.legend(loc = 'best')
plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.xlim(-2, 10)
plt.title('Multi-plot e.g. ', fontsize = 18)
- Forinformations:See
help(plt.plot)
繪製子圖
import numpy as np
import matplotlib.pyplot as plt
def pffcall(S, K):
return np.maximum(S - K, 0.0)
def pffput(S, K):
return np.maximum(K - S, 0.0)
S = np.linspace(50, 151, 100)
fig = plt.figure(figsize=(12, 6))
sub1 = fig.add_subplot(121) # col, row, num
sub1.set_title('Call', fontsize = 18)
plt.plot(S, pffcall(S, 100), 'r-', lw = 4)
plt.plot(S, np.zeros_like(S), 'black',lw = 1)
sub1.grid(True)
sub1.set_xlim([60, 120])
sub1.set_ylim([-10, 40])
sub2 = fig.add_subplot(122)
sub2.set_title('Put', fontsize = 18)
plt.plot(S, pffput(S, 100), 'r-', lw = 4)
plt.plot(S, np.zeros_like(S), 'black',lw = 1)
sub2.grid(True)
sub2.set_xlim([60, 120])
sub2.set_ylim([-10, 40])
- Figure: 一個子圖的例子 (註釋:這裏,可以把Figure,即fig理解爲一張大畫布,你把它分成了兩個子區域(sub1和sub2),然後在每個子區域各畫了一幅圖。)
在繪製的圖上添加文本和註釋 (Adding texts to plots)
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
def call(S, K=100, T=0.5, vol=0.6, r=0.05):
d1 = (np.log(S/K) + (r + 0.5 * vol**2) \
*T) / np.sqrt(T) / vol
d2 = (np.log(S/K) + (r - 0.5 * vol**2) \
*T) / np.sqrt(T) / vol
return S * norm.cdf(d1) - K * \
np.exp(-r * T) * norm.cdf(d2)
def delta(S, K=100, T=0.5, vol=0.6, r=0.05):
d1 = (np.log(S/K) + (r + 0.5 * vol**2)\
*T) / np.sqrt(T) / vol
return norm.cdf(d1)
(Code continues:)
S = np.linspace(40, 161, 100)
fig = plt.figure(figsize=(7, 6))
ax = fig.add_subplot(111)
plt.plot(S,(call(S)-call(100)),'r',lw=1)
plt.plot(100, 0, 'ro', lw=1)
plt.plot(S,np.zeros_like(S), 'black', lw = 1)
plt.plot(S,call(S)-delta(100)*S- \
(call(100)-delta(100)*100), 'y', lw = 1)
(Code continues:)
ax.annotate('$\Delta$ hedge', xy=(100, 0), \
xytext=(110, -10),arrowprops= \
dict(headwidth =3,width = 0.5, \
facecolor='black', shrink=0.05))
ax.annotate('Original call', xy= \
(120,call(120)-call(100)),xytext\
=(130,call(120)-call(100)),\
arrowprops=dict(headwidth =10,\
width = 3, facecolor='cyan', \
shrink=0.05))
plt.grid(True)
plt.xlim(40, 160)
plt.xlabel('Stock price', fontsize = 18)
plt.ylabel('Profits', fontsize = 18)
3D plot of a function with 2 variables
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
x, y = np.mgrid[-5:5:100j, -5:5:100j]
z = x**2 + y**2
fig = plt.figure(figsize=(8, 6))
ax = plt.axes(projection='3d')
surf = ax.plot_surface(x, y, z, rstride=1,\
cmap=cm.coolwarm, cstride=1, \
linewidth=0)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.title('3D plot of $z = x^2 + y^2$')
實驗3:atplotlib (Lab 3: Matplotlib)
- 用藍線繪製以下函數 (Plot the following function with blue line)
- 然後用紅點標記座標(1,2) (Then mark the coordinate (1, 2) with a red point.)
- 使用np.linspace()使t ∈ [0,2π]。 然後給 (Use np.linspace0 to make t ∈ [0,2π]. Then give)
- 針對X繪Y。 在這個情節中添加一個稱爲“Heart”的標題。 (Plot y against x. Add a title to this plot which is called "Heart" .)
- 針對x∈[-10,10], y∈[-10,10], 繪製3D函數 (Plot the 3D function for x∈[-10,10], y∈[-10,10])
Sympy
符號計算 (Symbolic computation)
到目前爲止,我們只考慮了數值計算。 (So far, we only considered the numerical computation.)
Python也可以通過模塊表徵進行符號計算。(Python can also work with symbolic computation via module sympy.)
符號計算可用於計算方程,積分等的顯式解。 (Symbolic computation can be useful for calculating explicit solutions to equations, integrations and so on.)
聲明一個符號變量 (Declare a symbol variable)
import sympy as sy
#聲明x,y爲變量
x = sy.Symbol('x')
y = sy.Symbol('y')
a, b = sy.symbols('a b')
#創建一個新符號(不是函數
f = x**2 + 2 - 2*x + x**2 -1
print(f)
#自動簡化
g = x**2 + 2 - 2*x + x**2 -1
print(g)
符號的使用1:求解方程 (Use of symbol 1: Solve equations)
import sympy as sy
x = sy.Symbol ('x')
y = sy.Symbol('y')
# 給定[-1,1] (give [-1, 1])
print(sy.solve (x**2 - 1))
# 不能證解決 (no guarantee for solution)
print(sy.solve(x**3 + 0.5*x**2 - 1))
# 用x的表達式表示y (exepress x in terms of y)
print (sy.solve(x**3 + y**2))
# 錯誤:找不到算法 (error: no algorithm can be found)
print(sy.solve(x**x + 2*x - 1))
符號的使用2:集成 (Use of symbol 2: Integration)
import sympy as sy
x = sy.Symbol('x')
y = sy.Symbol( 'y')
b = sy.symbols ( 'a b')
# 單變量 single variable
f = sy.sin(x) + sy.exp(x)
print(sy.integrate(f, (x, a, b)))
print(sy.integrate(f, (x, 1, 2)))
print(sy.integrate(f, (x, 1.0,2.0)))
# 多變量 multi variables
g = sy.exp(x) + x * sy.sin(y)
print(sy.integrate(g, (y,a,b)))
符號的使用3:分化 (Use of symbol 3: Differentiation)
import sympy as sy
x = sy.Symbol( 'x')
y = sy.Symbol( 'y')
# 單變量 (single variable)
f = sy.cos(x) + x**x
print(sy . diff (f , x))
# 多變量 (multi variables)
g = sy.cos(y) * x + sy.log(y)
print(sy.diff (g, y))