联合间接排序
联合间接排序支持为待排序列排序,若待排序列值相同,则利用参考序列作为参考继续排序。最终返回排序过后的有序索引序列。
indices = numpy.lexsort((参考序列, 待排序列))
案例:先按价格排序,再按销售量倒序排列。
#排序import numpy as npnames=np.array(['Apple','Mi','Oppo','Vivo','Huawei'])price = [8888,2999,3999,3999,49999]volume = np.array([50,100,90,88,110])#联合间接排序sorted_inds = np.lexsort((-volume,price))print(names[sorted_inds])
复数数组排序
按照实部的升序排列,对于实部相同的元素,参考虚部的升序,直接返回排序后的结果数组。
numpy.sort_complex(复数数组)
插入排序
若有需求需要向有序数组中插入元素,使数组依然有序,numpy提供了searchsorted方法查询并返回可插入位置数组。
indices = numpy.searchsorted(有序序列, 待插序列)
案例:
import numpy as np# 0 1 2 3 4 5 6a = np.array([1, 2, 4, 5, 6, 8, 9])b = np.array([7, 3])c = np.searchsorted(a, b)print(c)d = np.insert(a, c, b)print(d)
scipy提供了常见的插值算法可以通过 一组离散点得到符合这组散点分布规律插值器函数。若我们给插值器函数更多的散点x坐标序列,该函数将会返回相应的y坐标序列。
func = si.interp1d( 离散水平坐标, 离散垂直坐标, kind=插值算法(缺省为线性插值))
案例:
# scipy.interpolateimport scipy.interpolate as siimport numpy as npimport matplotlib.pyplot as mp# 原始数据 15组数据min_x = -50max_x = 50dis_x = np.linspace(min_x, max_x,15)dis_y = np.sinc(dis_x)mp.scatter(dis_x,dis_y,color='dodgerblue',s=70)#绘制线性插值器函数 通过一系列的散点设计出符合一定规律插值器函数,使用线性插值(kind缺省值)linear = si.interp1d(dis_x,dis_y)x = np.linspace(min_x,max_x,1000)y = linear(x)mp.plot(x,y)# 三次样条插值 (CUbic Spline Interpolation) 获得一条光滑曲线cubic = si.interp1d(dis_x, dis_y, kind='cubic')cub_x = np.linspace(min_x, max_x, 1000)cub_y = cubic(cub_x)mp.plot(cub_x,cub_y)mp.show()
积分
直观地说,对于一个给定的正实值函数,在一个实数区间上的定积分可以理解为坐标平面上由曲线、直线以及轴围成的曲边梯形的面积值(一种确定的实数值)。
利用微元法认识什么是积分。
案例:在[-5, 5]区间绘制二次函数y=2x2+3x+4的曲线:
#积分import numpy as npimport matplotlib.pyplot as mpdef f(x): return 2*x**2+3*x+4a,b = -5,5x=np.linspace(a,b,1000)y=f(x)mp.figure('Integral',facecolor='lightgray')mp.title('Integral',fontsize=16)mp.grid(linestyle=':')mp.plot(x,y,c='orangered',linewidth=6,label='f(x)')#计算f(x)在[-5,5]区间的定积分n=200x = np.linspace(a,b,n)y = f(x)area = 0for i in range(n-1): area+=(y[i]+y[i+1])*(x[1]-x[0])/2print(area)#206.67508396252612mp.legend()mp.show()
案例:微分法绘制函数在与x轴还有[-5, 5]所组成的闭合区域中的小梯形。
# 积分import numpy as npimport matplotlib.pyplot as mpimport matplotlib.patches as mcdef f(x): return 2 * x ** 2 + 3 * x + 4a, b = -5, 5x = np.linspace(a, b, 1000)y = f(x)mp.figure('Integral', facecolor='lightgray')mp.title('Integral', fontsize=16)mp.grid(linestyle=':')mp.plot(x, y, c='orangered', linewidth=6, label='f(x)')# 计算f(x)在[-5,5]区间的定积分n = 200x = np.linspace(a, b, n)y = f(x)area = 0for i in range(n - 1): area += (y[i] + y[i + 1]) * (x[1] - x[0]) / 2print(area) # 206.67508396252612for i in range(n - 1): mp.gca().add_patch(mc.Polygon([ [x[i], 0], [x[i], y[i]], [x[i + 1], y[i + 1]], [x[i + 1], 0]], fc='deepskyblue', ec='dodgerblue', alpha=0.5))mp.legend()mp.show()
调用scipy.integrate模块的quad方法计算积分:
import scipy.integrate as si# 利用quad求积分 给出函数f,积分下限与积分上限[a, b] 返回(积分值,最大误差)area = si.quad(f, a, b)[0]print(area)
import numpy as npimport scipy.integrate as sidef f(x): return 2 * x ** 2 + 3 * x + 4a, b = -5, 5x = np.linspace(a, b, 1000)y = f(x)#基于scipy求积分r = si.quad(f, -5, 5)print(r)#(206.66666666666669, 2.294460917558657e-12)
图像
scipy.ndimage中提供了一些简单的图像处理,如高斯模糊、任意角度旋转、边缘识别等功能。
# 图像import scipy.misc as smimport scipy.ndimage as snimport matplotlib.pyplot as mp# 读取文件img = sm.imread('lily.jpg', True)print(img.shape)#(512, 512)mp.figure('Ndimage', facecolor='lightgray')mp.subplot(221)mp.axis('off') # 关闭坐标轴mp.imshow(img, cmap='gray')# 高斯模糊img2 = sn.median_filter(img, 20) # 数越大越模糊,算法越复杂,越耗时mp.subplot(222)mp.axis('off')mp.imshow(img2, cmap='gray')# 旋转img3 = sn.rotate(img, 90) # 逆时针旋转mp.subplot(223)mp.axis('off')mp.imshow(img3, cmap='gray')# 边缘识别img4 = sn.prewitt(img)mp.subplot(224)mp.axis('off')mp.imshow(img4, cmap='gray')mp.tight_layout()mp.show()
# 金融相关APIimport numpy as np# 终值 = np.fv(利率, 期数, 每期支付, 现值)# 将1000元以1%的年利率存入银行5年,每年加存100元,# 到期后本息合计多少钱?fv = np.fv(0.01, 5, -100, -1000)print(round(fv, 2)) # 1561.11# 现值 = np.pv(利率, 期数, 每期支付, 终值)# 将多少钱以1%的年利率存入银行5年,每年加存100元,# 到期后本息合计2000元?pv = np.pv(0.01, 5, -100, 2000)print(pv) # -1417.588251280984# 净现值 = np.npv(利率, 现金流)# 将1000元以1%的年利率存入银行5年,每年加存100元,# 相当于一次性存入多少钱?npv = np.npv(0.01, [ -1000, -100, -100, -100, -100, -100])print(round(npv, 2)) # -1485.34fv = np.fv(0.01, 5, 0, npv)print(round(fv, 2)) # 1561.11# 内部收益率 = np.irr(现金流)# 将1000元存入银行5年,以后逐年提现100元、200元、# 300元、400元、500元,银行利率达到多少,可在最后# 一次提现后偿清全部本息,即净现值为0元?irr = np.irr([-1000, 100, 200, 300, 400, 500])print(round(irr, 2)) # 0.12npv = np.npv(irr, [-1000, 100, 200, 300, 400, 500])print(npv) # 0.0# 每期支付 = np.pmt(利率, 期数, 现值)# 以1%的年利率从银行贷款1000元,分5年还清,# 平均每年还多少钱?pmt = np.pmt(0.01, 5, 1000)print(round(pmt, 2)) # -206.04#多还的钱print(round(pmt, 2) * 5 + 1000) # -30.200000000000045# 期数 = np.nper(利率, 每期支付, 现值)# 以1%的年利率从银行贷款1000元,平均每年还pmt元,# 多少年还清?nper = np.nper(0.01, pmt, 1000)print(int(nper)) # 5# 利率 = np.rate(期数, 每期支付, 现值, 终值)# 从银行贷款1000元,平均每年还pmt元,nper年还清,# 年利率多少?rate = np.rate(nper, pmt, 1000, 0)print(round(rate, 2)) # 0.01