首頁 > 軟體

python數學建模(SciPy+ Numpy+Pandas)

2022-07-03 18:00:32

前言

SciPy 是一個開源的 Python 演演算法庫和數學工具包, Scipy 是基於 Numpy 的科學計算庫,用於數學、科學、工程學等領域。
SciPy庫依賴於NumPy,它提供了便捷且快速的N維陣列操作。
SciPy庫的構建與NumPy陣列一起工作,並提供了許多使用者友好和高效的數位實踐,
並在天文學、生物學、氣象學和氣候科學,以及材料科學等多個學科得到了廣泛應用。
NumPy和SciPy易於使用,強大到足以依靠世界上一些頂尖的科學家和工程師。

SciPy 學習

'''
SciPy 包含的模組有最佳化、線性代數、積分、插值、特殊函數、快速傅立葉變換、
訊號處理和影象處理、常微分方程求解和其他科學與工程中常用的計算。
'''
# 安裝scipy庫:
# SciPy終端安裝命令:pip install SciPy
# https://www.runoob.com/w3cnote/python-pip-install-usage.html  Python pip 安裝與使用
# 檢視scipy版本:
import scipy
print(scipy.__version__)
# SciPy模組功能表
'''
模組              功能
scipy.cluster   聚類分析等
scipy.constants 物理和數學函數
scipy.fftpack   傅立葉變換
scipy.integrate 積分
scipy.interpolate   插值
scipy.io        資料輸入和輸出
scipy.linalg    線性代數
scipy.ndimage   n維影象
scipy.odr       正交距離迴歸
scipy.optimize  優化
scipy.signal    訊號處理
scipy.sparse    稀疏矩陣
scipy.spatial   空間資料結構和演演算法
scipy.special   特殊函數
scipy.stats     統計
'''
# 使用 dir() 函數來檢視 constants 模組包含的常數:
from scipy import constants
print(dir(constants))
'''
單位型別
常數模組包含以下幾種單位:
公制單位
二進位制,以位元組為單位
質量單位
角度換算
時間單位
長度單位
壓強單位
體積單位
速度單位
溫度單位
能量單位
功率單位
力學單位
'''
print()
# SciPy 常數模組:
# constants 是 scipy 的常數模組
from scipy import constants
# 檢視一英畝等於多少平方米:
print(constants.acre)   # 輸出 4046.8564223999992
# SciPy 常數模組 constants 提供了許多內建的數學常數
# 圓周率:  pi
# 黃金比例: golden
from scipy import constants
print(constants.pi)         # 輸出 3.141592653589793 【圓周率】
print(constants.golden)     # 輸出 1.618033988749895 【黃金比例】

1-SciPy基本操作

1-1求解非線性方程(組)

1-1

解題程式碼如下:

# scipy.optimize模組的fsolve和root可求非線性方程(組)的解
# 格式:
from scipy.optimize import fsolve
from scipy.optimize import root
# fsolve或root求解非線性方程組時,先把非線性方程組寫成 F(x)=0 這樣的形式【x:向量;F(x):向量函數】
fx = lambda x: x**980-5.01*x**979-3.388*x**977
    +7.398*x**978-x**3+5.01*x**2-7.398*x+3.388
x1 = fsolve(fx, 1.5, maxfev=420)     # 函數呼叫420次【呼叫小了,會報警告】
x2 = root(fx, 1.5)
print(x1)   # 相當於答案
print()
print(x2)   # 相當於解題過程

執行x1、x2結果如下:

1-2

解題程式碼如下:

from scipy.optimize import fsolve, root
fs2 = lambda s: [s[0]**2+s[1]**2-1, s[0]-s[1]]
s1 = fsolve(fs2, [1, 1])
print()
s2 = root(fs2, [1, 1])
print(s1)	# 輸出 [0.70710678 0.70710678]
print()
print(s2)

執行s2效果如下:

1-2積分

scipy.integrate模組提供了多種積分模式。

積分主要分為以下兩類:

  • 對給定函數的數值積分
  • 對給定離散點的數值積分,函數有trapz

題目:

'''
函數                                              說明
quad(func, a, b, args)                      計算一重數值積分
dblquad(func, a, b, gfun, hfun, args)       計算二重數值積分
tplquad(func, a, b, gfun, hfun, qfun, rfun) 計算三重數值積分
nquad(func, ranges, args)                   計算多變數積分
'''
from scipy.integrate import quad

def func(x, a, b):
    return a*x**2+b*x
z1 = quad(func, 0, 1, args=(2, 1))
z2 = quad(func, 0, 1, args=(2, 10))
print(z1)   # 輸出 (1.1666666666666665, 1.2952601953960159e-14)
print(z2)   # 輸出 (5.666666666666667, 6.291263806209221e-14)
# 注:輸出的後一個值為積分值的絕對誤差

1-3最小二乘解

# 最小二乘解
# scipy.optimize 模組求非線性方程組最小二乘解格式:
'''
from scipy.optimize import least_squares
least_squares(fun, x0)
注:用到loadtxt需自行準備好檔案【準備檔案】
'''
from scipy.optimize import least_squares
import numpy as np
s = np.loadtxt('data.txt')
x0 = s[0]
y0 = s[1]
d = s[2]
fs = lambda x: np.sqrt((x0-s[0])**2+(y0-s[1])**2-d)
xc = least_squares(fs, np.random.rand(2))
print(xc)
print()
print(xc.s)

1-4最大模特徵值及對應的特徵向量

題目:

# 4-最大模特徵值及對應的特徵向量
# 題目描述:求下列矩陣的最大模特徵值及對應的特徵向量:
from scipy.sparse.linalg import eigs
import numpy as np
m = np.array([
    [1, 2, 3],
    [2, 1, 3],
    [3, 3, 6]
], dtype=float)
a, b = np.linalg.eig(m)
c, d = eigs(m, 1)
print('最大模特徵值為:', c)    # 輸出 最大模特徵值為: [9.+0.j]
print('對應的特徵向量:n', d)

執行結果如下:

Numpy學習(續)

# NumPy 廣播(Broadcast)
# 廣播是 numpy 對不同形狀的陣列進行數值計算的方式, 對陣列的算術運算通常在相應的元素上進行。

# 如果兩個陣列 a 和 b 形狀相同,即滿足 a.shape == b.shape,那麼 a*b 的結果就是 a 與 b 陣列對應位相乘。
# 這要求維數相同,且各維度的長度相同。
'''
對兩個陣列,分別比較他們的每一個維度(若其中一個陣列沒有當前維度則忽略),滿足:
陣列擁有相同形狀。
當前維度的值相等。
當前維度的值有一個是 1。
若條件不滿足,丟擲 "ValueError: frames are not aligned" 異常

'''
import numpy as np
a = np.array([3, 6, 9])
b = np.array([2, 4, 6])
c = a * b
print(c)    # 輸出 [ 6 24 54]
# 若形狀不同時,numpy 將自動觸發廣播機制
import numpy as np
x = np.array([
    [4, 2, 5],
    [5, 2, 0],
    [2, 6, 1],
    [1, 4, 5]
])
y = np.array([3, 1, 2])
print(x+y)
yy = np.tile(y, (4, 1))     # 重複b的各個維度
print(x+yy)

1-Numpy 數學函數

1-1三角函數

# NumPy 數學函數
# NumPy 包含大量的各種數學運算的函數,包括三角函數,算術運算的函數,複數處理常式等。

# 1-三角函數
# NumPy 提供了標準的三角函數:sin()、cos()、tan()。
import numpy as np

lxw = np.array([0, 30, 45, 60, 90])

# sin()
zx = np.sin(lxw*np.pi/180)
print(zx)
# 計算角度的反正弦【單位:弧度】
fzx = np.arcsin(zx)
print(fzx)
# 檢查結果【通過轉化為角度制】
jg = np.degrees(fzx)
print(jg)   # 輸出 [ 0. 30. 45. 60. 90.]
# cos()
yx = np.cos(lxw*np.pi/180)
print(yx)
# 反餘弦
fyx = np.arccos(yx)
print(fyx)
# 檢查結果:
jg2 = np.degrees(fyx)
print(jg2)  # 輸出 [ 0. 30. 45. 60. 90.]
# tan()
zq = np.tan(lxw*np.pi/180)
print(zq)

# 反正切
fzq = np.arctan(zq)
print(fzq)
# 檢查結果:
jg3 = np.degrees(fzq)
print(jg3)  # 輸出 [ 0. 30. 45. 60. 90.]

2-舍入函數

2-1 numpy.around()

# 2-舍入函數
# 2-1 numpy.around()
'''
numpy.around() 函數返回指定數位的四捨五入值。
格式:
numpy.around(a,decimals)
引數說明:
a: 陣列
decimals: 舍入的小數位數。 預設值為0。 如果為負,整數將四捨五入到小數點左側的位置

'''
import numpy as np
bl = np.array([15.222, 22.6555, 13.71111])
print(np.around(bl))        # 輸出 [15. 23. 14.]
print(np.around(bl, 2))     # 輸出 [15.22 22.66 13.71]
print(np.around(bl, -1))    # 輸出 [20. 20. 10.]

2-2 numpy.floor()

# 2-2 numpy.floor()
# numpy.floor() 返回小於或者等於指定表示式的最大整數,即向下取整
import numpy as np
xx = np.array([23.3, 13.43, 2.9])
print(np.floor(xx))     # 輸出 [23. 13.  2.]

2-3 numpy.ceil()

# 2-3 numpy.ceil()
# numpy.ceil() 返回大於或者等於指定表示式的最小整數,即向上取整
import numpy as np
xs = np.array([23.1, 23.5, 54.9])
print(np.ceil(xs))      # 輸出 [24. 24. 55.]

3-Numpy算術函數

NumPy 算術函數包含簡單的加減乘除: add(),subtract(),multiply() 和 divide()

  • 倒數:reciprocal()
  • 冪:power()
  • 餘數:mod() | remainder()

:陣列必須具有相同的形狀符合陣列廣播規則

相關程式碼如下:

import numpy as np
sz = np.arange(9, dtype=np.float_).reshape(3, 3)
sz2 = np.array([5, 2, 1])   # 注:如果相除,這裡是被除數的話,裡面不能有0
# 陣列相加
xj = np.add(sz, sz2)
print(xj)
# 陣列相減
xj2 = np.subtract(sz, sz2)
print(xj2)
# 陣列相乘
xc = np.multiply(sz, sz2)
print(xc)
# 陣列相除
xc2 = np.divide(sz, sz2)
print(xc2)
print()
# numpy.power()
# numpy.power() 函數將第一個輸入陣列中的元素作為底數,計算它與第二個輸入陣列中相應元素的冪
import numpy as np
m = np.array([1, 4, 8])     # 陣列1
mc = np.power(m, 3)         # 陣列1所有元素對應的3次方
print(mc)   # 輸出 [  1  64 512]
m2 = np.array([1, 2, 3])    # 陣列2
mc2 = np.power(m, m2)       # 陣列1作為底數,陣列2作為冪
print(mc2)  # 輸出 [  1  16 512]
print()
# numpy.mod()
# numpy.mod() 計算輸入陣列中相應元素的相除後的餘數
# 函數 numpy.remainder() 也產生相同的結果
import numpy as np
sz1 = np.array([23, 45, 67])
sz2 = np.array([2, 3, 5])
print(np.mod(sz1, sz2))         # 輸出 [1 0 2]
print(np.remainder(sz1, sz2))   # 輸出 [1 0 2]

Pandas學習(續)

# pandas的SettingWithCopyWarning

# pandas的SettingWithCopyWarning報警復現、原因、解決方案
# 讀取資料
import pandas as pd
df = pd.read_csv('nba.csv')
print(df.head())
# 核心解決問題:pandas的dataframe的修改寫操作,只允許在源dataframe上進行,一步到位
# 解決方法(兩種):
'''
1-將get+set的兩步操作,改成set的一步操作
2-若須處理篩選資料做後續的處理分析,使用copy複製dataframe

'''
# pandas不允許先篩選子dataframe,在進行修改寫入

注意先準備好csv檔案

Pandas 資料排序

Series的排序:

# Pandas 資料排序
'''
Series的排序:
Series.sort_values(ascending=True, inplace=False)
引數說明:
    · ascending: 預設為True升序排序,False為False
    · inplace:   是否修改原始Series

DataFrame的排序:
DataFrame.sort_values(by, ascending=True, inplace=False)
引數說明:
    · by:字串或者List<字串>,單列排序或者多列排序
    · ascending: bool或者List,升序還是降序
    · inplace:   是否修改原始DataFrame

'''
# Series的排序:
import pandas as pd
df = pd.read_csv('nba.csv')
print(df.head())		# 輸出前五行
print(df['Weight'].sort_values())                      # 升序排序
print(df['Weight'].sort_values(ascending=False))       # 降序排序

執行結果分別如下:

DataFrame的排序

# DataFrame的排序
# 單列排序:
print(df.sort_values(by='Weight'))

執行部分結果如下:

print(df.sort_values(by="Weight", ascending=False))     # 降序排序

# 多列排序:
print(df.sort_values(by=['Age', 'Weight']))

# 兩個欄位都是降序排序
print(df.sort_values(by=['Age', 'Weight'], ascending=False))

# 分別指定升序還是降序
print(df.sort_values(by=['Age', 'Weight'], ascending=[False, True]))

Pandas字串處理

之前我就在這個字串處理的題上出了一些問題(不過當天就解決啦)【今天在來看看】,也就是

df['lrl'].str.replace("%", "").astype("int32")
# Pandas字串處理:
'''
1-使用方法:先獲取Series的屬性,然後再屬性上呼叫函數
2-只能在字串列上使用,不能再數位列上使用
3-DataFrame沒有str屬性和使用
4-Series.str並不是原生Python字串,它是封裝的一套方法
'''
# 獲取Series的屬性
# print(df['Salary'].str)   # 報錯【示範】

# AttributeError: Can only use .str accessor with string values!
# AttributeError:只能使用。帶字串值的str存取器!

# 一定得是字串列
print(df['College'].str)
# 執行結果為: <pandas.core.strings.accessor.StringMethods object at 0x00000204444EBC48>
# 判斷是不是數位列
print(df['College'].str.isnumeric())
# print(df['College'].len)      # 報錯【示範】

# AttributeError: 'Series' object has no attribute 'len'
# AttributeError:「Series」物件沒有屬性「len」

# 使用str的startswith、contains等得到bool的Series可以做條件查詢
tj = df['Height'].str.startswith("6-2")
print(tj)

# 去掉Height中間的「-」
print(df['Height'].str.replace("-", ""))

# 取第一位數
print(df['Height'].str.replace("-", "").str.slice(0, 1))

# 同上
print(df['Height'].str.replace("-", "").str[0:1])

到此這篇關於python數學建模(SciPy+ Numpy+Pandas)的文章就介紹到這了,更多相關pyth Pandas內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com