日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)Python教程:Python數(shù)學(xué)建模三劍客之Scipy

沁陽ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

三劍客之Scipy

前面已經(jīng)說過,最初的numpy其實是scipy的一部分,后來才從scipy中分離出來。scipy函數(shù)庫在numpy庫的基礎(chǔ)上增加了眾多的數(shù)學(xué)、科學(xué)以及工程計算中常用的庫函數(shù)。例如線性代數(shù)、常微分方程數(shù)值求解、信號處理、圖像處理、稀疏矩陣等等。由于其涉及的領(lǐng)域眾多,我之于scipy,就像盲人摸大象,只能是摸到哪兒算哪兒。

一、插值

數(shù)據(jù)插值是數(shù)據(jù)處理過程中經(jīng)常用到的技術(shù),常用的插值有一維插值、二維插值、高階插值等,常見的算法有線性插值、B樣條插值、臨近插值等。

1、一維插值

一維插值最常用的算法是線型插值和三階樣條插值,此外還有前點插值、后點插值、臨近點插值、零階插值(等同于前點插值)、一階插值(等同于線性插值)、五階插值等。下面的例子對以上8中插值方法進行了比較。

import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['FangSong']
plt.rcParams['axes.unicode_minus'] = False
x = np.linspace(0,10,11)
y = np.exp(-x/3.0)
x_new = np.linspace(0,10,100) # 期望在0-10之間變成100個數(shù)據(jù)點
f1 = interpolate.interp1d(x, y, kind='linear')
f2 = interpolate.interp1d(x, y, kind='nearest')
f3 = interpolate.interp1d(x, y, kind='zero')
f4 = interpolate.interp1d(x, y, kind='slinear')
f5 = interpolate.interp1d(x, y, kind='cubic')
f6 = interpolate.interp1d(x, y, kind='quadratic')
f7 = interpolate.interp1d(x, y, kind='previous')
f8 = interpolate.interp1d(x, y, kind='next')
plt.figure('Demo', facecolor='#eaeaea')
plt.subplot(221)
plt.plot(x, y, "o",  label=u"原始數(shù)據(jù)")
plt.plot(x_new, f2(x_new), label=u"臨近點插值")
plt.plot(x_new, f7(x_new), label=u"前點插值")
plt.plot(x_new, f8(x_new), label=u"后點線性插值")
plt.legend()
plt.subplot(222)
plt.plot(x, y, "o",  label=u"原始數(shù)據(jù)")
plt.plot(x_new, f1(x_new), label=u"線性插值")
plt.plot(x_new, f3(x_new), label=u"零階樣條插值")
plt.plot(x_new, f4(x_new), label=u"一階樣條插值")
plt.legend()
plt.subplot(223)
plt.plot(x, y, "o",  label=u"原始數(shù)據(jù)")
plt.plot(x_new, f1(x_new), label=u"線性插值")
plt.plot(x_new, f5(x_new), label=u"三階樣條插值")
plt.legend()
plt.subplot(224)
plt.plot(x, y, "o",  label=u"原始數(shù)據(jù)")
plt.plot(x_new, f1(x_new), label=u"線性插值")
plt.plot(x_new, f6(x_new), label=u"五階樣條插值")
plt.legend()
plt.show()

不同的插值方法畫在一起,對比之下效果會比較明顯:

2、二維插值

二維數(shù)據(jù),通??偸菍?yīng)著一個網(wǎng)格,比如,經(jīng)緯度網(wǎng)格。如果插值對象只有一個二維數(shù)組,那么我們可以用數(shù)組的行列號來構(gòu)造網(wǎng)格。

import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['FangSong']
plt.rcParams['axes.unicode_minus'] = False
y, x = np.mgrid[-2:2:20j,-3:3:30j] # 30x20 = 600
z = x*np.exp(-x**2-y**2)
y_new, x_new = np.mgrid[-2:2:80j,-3:3:120j] # 120x80 = 9600
f1 = interpolate.interp2d(x[0,:], y[:,0], z, kind='linear') # 線性插值
f2 = interpolate.interp2d(x[0,:], y[:,0], z, kind='cubic') # 三階樣條
f3 = interpolate.interp2d(x[0,:], y[:,0], z, kind='quintic') # 五階樣條
z1 = f1(x_new[0,:], y_new[:,0])
z2 = f2(x_new[0,:], y_new[:,0])
z3 = f3(x_new[0,:], y_new[:,0])
plt.subplot(221)
plt.pcolor(x, y, z, cmap=plt.cm.hsv)
plt.colorbar()
plt.axis('equal')
plt.subplot(222)
plt.pcolor(x_new, y_new, z1, cmap=plt.cm.hsv)
plt.colorbar()
plt.axis('equal')
plt.subplot(223)
plt.pcolor(x_new, y_new, z2, cmap=plt.cm.hsv)
plt.colorbar()
plt.axis('equal')
plt.subplot(224)
plt.pcolor(x_new, y_new, z3, cmap=plt.cm.hsv)
plt.colorbar()
plt.axis('equal')
plt.show()

原始數(shù)據(jù)、線型插值數(shù)據(jù)、三階插值數(shù)據(jù)、五階插值數(shù)據(jù)的效果對比如下:

二、擬合

在工作中,我們常常需要在圖中描繪某些實際數(shù)據(jù)觀察的同時,使用一個曲線來擬合這些實際數(shù)據(jù)。所謂擬合,就是找出符合數(shù)據(jù)變化趨勢的曲線方程,進而對變化趨勢做出預(yù)測。

1、使用numpy.polyfit擬合

numpy.polyfit() 實現(xiàn)了最小二乘法,其功能是返回指定次數(shù)的多項式參數(shù),這組參數(shù)使得多項式和樣本數(shù)據(jù)的誤差為最小。下面的代碼,虛擬了谷神星的一段觀測數(shù)據(jù),籍此使用最小二乘法實現(xiàn)多項式擬合,進而推測出谷神星未來的運行軌跡。最后和虛擬的運行軌道方程比較。

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['FangSong']
plt.rcParams['axes.unicode_minus'] = False
def f(t):
    """谷神星虛擬的運行軌道方程。我們假裝不知道,僅用來驗證預(yù)測結(jié)果是否準確"""
    
    t = t/7.5 -1
    return ((t**2-1)**3 + 0.5)*np.sin(2*t)
t = np.linspace(0, 20, 201) # 用于繪制實際的運行軌跡線
_x = np.linspace(0, 15, 16) # 觀測數(shù)據(jù)時間序列
_y = f(_x) # 觀測數(shù)據(jù)位置序列
x = np.linspace(15, 20, 6) # 待預(yù)測的時間序列
loss_list = list()
for i in range(2,16): # 從2次到15次多項式,逐一計算誤差
    args = np.polyfit(_x, _y, i) # 用最小二乘法找到一組系數(shù)
    g = np.poly1d(args) # 用這組系數(shù)生成方程g(x)
    loss = np.sum(np.square(g(_x)-_y)) # 計算i次多項式擬合的誤差
    loss_list.append(loss)
    print(i, loss)
k = loss_list.index(min(loss_list))+2
args = np.polyfit(_x, _y, k)
g = np.poly1d(args)
plt.figure('demo', facecolor='#eaeaea')
plt.plot(_x, _y, c='r', ls='', marker='o', label=u'觀測數(shù)據(jù)')
plt.plot(_x, g(_x), c='b', ls='-', label=u'%d次多項式擬合,誤差%0.8f'%(k, loss_list[k-2]))
plt.plot(x, g(x), c='r', ls=':', label=u'預(yù)測軌跡')
plt.plot(t, f(t), c='#60f0f0', ls='--', label=u'實際運行軌跡')
plt.legend(loc='lower left')
plt.show()

將虛擬的運行軌道、虛擬的觀測數(shù)據(jù)、擬合曲線、預(yù)測曲線繪制在一起,效果如下:

2、使用scipy.optimize.optimize.curve_fit擬合

不管曲線實際是什么樣的,多項式擬合總是以一個有限次的多項式去逼近數(shù)據(jù)樣本。還有一種擬合,就是我們知道曲線的標準方程,但有些系數(shù)或參數(shù)不確定,這樣的擬合,也是要找到最佳系數(shù)或參數(shù)。scipy提供的擬合,需要先確定帶參數(shù)的曲線方程,然后由scipy求解方程,返回曲線參數(shù)。

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy import optimize
>>> x = np.arange(1,13,1)
>>> y = np.array([17,19,21,28,33,38,37,37,31,23,19,18 ])
>>> plt.plot(x, y)
[]
>>> plt.show()

可以看出,曲線近似正弦函數(shù)。構(gòu)建函數(shù)y=asin(xpi/6+b)+c,使用scipy的optimize.curve_fit函數(shù)求出a、b、c的值:

>>> def fmax(x,a,b,c):
return a*np.sin(x*np.pi/6+b)+c
>>> fita, fitb = optimize.curve_fit(fmax, x, y, [1,1,1])
>>> print fita
[ 10.93254951  -1.9496096   26.75      ]
>>> xn = np.arange(1,13,0.1)
>>> plt.plot(x, y)
[]
>>> plt.plot(xn, fmax(xn, fita[0],fita[1],fita[2]))
[]
>>> plt.show()

三、求解非線性方程(組)

在數(shù)學(xué)建模中,需要對一些稀奇古怪的方程(組)求解,Matlab自然是首選,但Matlab不是免費的,scipy則為我們提供了免費的午餐!scipy.optimize庫中的fsolve函數(shù)可以用來對非線性方程(組)進行求解。它的基本調(diào)用形式如下:

fsolve(func, x0)

func(x)是計算方程組誤差的函數(shù),它的參數(shù)x是一個矢量,表示方程組的各個未知數(shù)的一組可能解,func返回將x代入方程組之后得到的誤差;x0為未知數(shù)矢量的初始值。

我們先來求解一個簡單的方程:$ \sin(x) - \cos(x) = 0.2$

>>> from scipy.optimize import fsolve
>>> import numpy as np
>>> def f(A):
x = float(A[0])
return [np.sin(x) - np.cos(x) - 0.2]
>>> result = fsolve(f, [1])
array([ 0.92729522])
>>> print result
[0.92729522]
>>> print f(result)
[2.7977428707082197e-09]

哈哈,易如反掌!再來一個方程組:

>>> from scipy.optimize import fsolve
>>> import numpy as np
>>> def f(A):
x = float(A[0])
y = float(A[1])
z = float(A[2])
return [4*x*x - 2*np.sin(y*z), 5*y + 3, y*z - 1.5]
>>> result = fsolve(f, [1, 1, 1])
>>> print result
[-0.70622057 -0.6        -2.5       ]
>>> print f(result)
[-9.1260332624187868e-14, 0.0, 5.329070518200751e-15]

四、數(shù)值積分

數(shù)值積分是對定積分的數(shù)值求解,例如可以利用數(shù)值積分計算某個形狀的面積。我們知道,半徑為1的圓的方程可寫成:

下面讓我們來考慮一下如何計算半徑為1的半圓的面積,根據(jù)圓的面積公式,其面積應(yīng)該等于PI/2。單位半圓曲線可以用下面的函數(shù)表示:

我們先定義一個計算根據(jù)x計算y的函數(shù):

>>> def half_circle(x):
return (1-x**2)**0.5

1、經(jīng)典微分法

下面的程序使用經(jīng)典的分小矩形計算面積總和的方式,計算出單位半圓的面積:

>>> N = 10000
>>> x = np.linspace(-1, 1, N)
>>> dx = 2.0/N
>>> y = half_circle(x)
>>> dx * np.sum(y[:-1] + y[1:]) # 面積的兩倍
3.1412751679988937

2、使用定積分求解函數(shù)

如果我們調(diào)用scipy.integrate庫中的quad函數(shù)的話,將會得到非常精確的結(jié)果:

>>> from scipy import integrate
>>> pi_half, err = integrate.quad(half_circle, -1, 1)
>>> pi_half*2
3.1415926535897984

五、圖像處理

在scipy.misc模塊中,有一個函數(shù)可以載入Lena圖像——這副圖像是被用作圖像處理的經(jīng)典示范圖像。我只是簡單展示一下在該圖像上的幾個操作。

(1)載入Lena圖像,并顯示灰度圖像

(2)應(yīng)用中值濾波掃描信號的每一個數(shù)據(jù)點,并替換為相鄰數(shù)據(jù)點的中值

(3)旋轉(zhuǎn)圖像

(4)應(yīng)用Prewitt濾波器(基于圖像強度的梯度計算)

>>> from scipy import misc
>>> from scipy import ndimage
>>> img = misc.lena().astype(np.float32)
>>> plt.subplot(221)
>>> plt.title('Original Image')
>>> plt.imshow(img, cmap=plt.cm.gray)
>>> plt.subplot(222)
>>> plt.title('Median Filter')
>>> filtered = ndimage.median_filter(img, size=(42,42))
>>> plt.imshow(filtered, cmap=plt.cm.gray)
>>> plt.subplot(223)
>>> plt.title('Rotated')
>>> rotated = ndimage.rotate(img, 90)
>>> plt.imshow(rotated, cmap=plt.cm.gray)
>>> plt.subplot(224)
>>> plt.title('Prewitt Filter')
>>> filtered = ndimage.prewitt(img)
>>> plt.imshow(filtered, cmap=plt.cm.gray)
>>> plt.show()

python創(chuàng)新互聯(lián)教程,大量的免費python視頻教程,歡迎在線學(xué)習(xí)!

相關(guān)推薦:

1、Python數(shù)學(xué)建模三劍客之Numpy

2、Python數(shù)學(xué)建模三劍客之Matplotlib


文章名稱:創(chuàng)新互聯(lián)Python教程:Python數(shù)學(xué)建模三劍客之Scipy
標題鏈接:http://www.dlmjj.cn/article/dhpccjo.html