likes
comments
collection
share

推荐收藏!2万字图解Numpy

作者站长头像
站长
· 阅读数 18

大家好,今天我用图解的方式讲解Numpy的用法,内容较长建议收藏,梳理不易,点赞支持。

学习 Python 编程,给我的经验就是:技术要学会分享、交流,不建议闭门造车。一个人可能走的很快、但一堆人可以走的更远。如果你希望技术交流,可以关注我

关注公众号:Python技术训练营

解锁 《python百万字教程,手把手助你从零进阶拿高薪》,让学习更贴近未来实战

内容包含

python百万字教程,手把手助你从零进阶拿高薪(十一模块)

1.hello,初识python

2.python大数据技术体系

3.AI研发,快人一步

4.全栈开发体系,你不能错过的内容

5.掌握核心,python核心编程

6.python并发编程

7.python数据库编程

8.爬虫入门必学

9.python框架源码分析

10.爬虫必备JS逆向

11.多学一点,加薪更稳定Android逆向

整理不易,关注一下吧ღ( ´・ᴗ・` )比心🤔

一丶Numpy常用函数介绍(1)--工具安装及Numpy介绍

1.NumPy(Numerical Python)

NumPy是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,也针对数组运算提供大量的数学函数库。NumPy 为开放源代码并且由许多协作者共同维护开发,是一个运行速度非常快的数学库,用于数组计算。

NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用,可广泛用于替代 MatLab,是一个强大的科学计算环境,便于后期学习数据科学和者机器学习。 SciPy 是一个开源的 Python 算法库和数学工具包, 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。

Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面,是为利用通用的图形用户界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口(API),前期在数据可视化中做作过简单的介绍。

1、numpy中的数组操作及代码

NumPy中的ndarray是一个多维数组对象,该对象由两部分组成:实际的数据和描述这些数据的元数据,大部分的数组操作仅仅修改元数据部分。

import numpy as np  #导入numpy包,并另命令为np

a = np.arange(5)  # 调用numpy中的函数arange,函数创建数组
print(a.dtype)   # 打印出数组a的数据类型
print(a.shape)  #数组的 shape 属性返回一个元组(tuple),元组中的元素即为NumPy数组每一个维度上的大小
print('\n')
#创建多维数组
m = np.array([np.arange(5), np.arange(5)]) #列表作为参数传给array函数,从而创建了一个5×2的数组
print(m)

#选取数组元素
print(m[0,0])
print(m[0,1])
print(m[1,1])
print(m[1,2])
print(m[1,3])

# NumPy 自定义的异构数据类型,该数据类型包括一个用字符串记录的名字、一个用
# 整数记录的数字以及一个用浮点数记录的价格 
t = np.dtype([('name', np.str_, 40), ('numitems', np.int32), ('price',np.float32)])
print(t)

# 一维数组的索引和切片
a = np.arange(9)
print(a[3:7])
print('\n')
#多维数组的切片和索引
b = np.arange(24).reshape(2,3,4)  #reshape函数的作用是改变数组的“形状”,也就是改变数组的维度
#其参数为一个正整数元组,分别指定数组在每个维度上的大小

print(b.shape)
print('\n')
print(b)
print('\n')
print(b[0])
print('\n')
print(b[:,0,0]) #下标用英文标点的冒号:来代替,表示不限该位置的参数,即打印出b的第1行,第1列的所有元组的数据。

运行结果如下: 推荐收藏!2万字图解Numpy 至于具体更详细的用法,可以多试试。

2.numpy改变数组的维度

上述的reshape函数可以将一维数组[0,1,2,...,23]转变为具有2个元素,每个元素是一个二维数组的三维数组,同样,也可以将多维数组转变为一维数组(将数组展平)。

可以用 ravel 等函数完成相关操作,见如下代码:

import numpy as np  #导入numpy包,并另命令为np

c = np.array([   #先定义一个numpy的多维数组
    [[0,1,2,3],[4,5,6,7],[8,9,10,11]],
    [[12,13, 14,15],[16,17,18,19],[20,21,22,23]]
     ])
e=d=c  
print (c.ravel())
print('\n')
print(c.flatten())
print('\n')
#用元组设置维度
d.shape = (6,4)
print(d)
print('\n')
# transpose用于转置,即行列互换,即线性代数中的转置矩阵
print(e.transpose())

运行结果: 推荐收藏!2万字图解Numpy

3.数组的组合

NumPy数组有水平组合、垂直组合和深度组合等多种组合方式,使用 vstack 、dstack 、 hstack 、 column_stack 、 row_stack 以及 concatenate 等函数来完成数组的组合。

import numpy as np  #导入numpy包,并另命令为np

a = np.arange(9).reshape(3,3)#定义a33列的二维数组
b=2*a #定义b,且b的每个元素均为a的两倍。

print(a)  #打印出a数列
print('\n')
print(b) #打印出b数列print('\n')

运行结果: 推荐收藏!2万字图解Numpy 分别看一下组合后的运行结果,代码如下:

import numpy as np  #导入numpy包,并另命令为np

a = np.arange(9).reshape(3,3)   #定义a33列的二维数组
b=2*a  #定义b,且b的每个元素均为a的两倍,数组结构与a一致。

#水平组合:将ndarray对象构成的元组作为参数,传给hstack 函数
print(np.hstack((a, b)))  #水平组合
print('\n')
print(np.concatenate((a, b), axis=1))  #注意axis参数
print('\n')
#垂直组合
print(np.vstack((a, b)))
print('\n')
print(np.concatenate((a, b), axis=0))#注意axis=0是默认值,即可以不设置。
print('\n')

运行结果如下: 推荐收藏!2万字图解Numpy 很明显,上述函数np.hstack((a,b))的结果显示为将a的行与b的行连成一个更长的行(np.concatenate()函数一样,只是多了一个参数),相当于增加了数组的列数。

而np.vstack((a,b)),则是结合成具有更多的行,而列数不变。用二维表示如下:

推荐收藏!2万字图解Numpy 接下来看一下深度组合、列组合、行组合

import numpy as np  #导入numpy包,并另命令为np

a = np.arange(9).reshape(3,3)   #定义a为3行3列的二维数组
b=2*a  #定义b,且b的每个元素均为a的两倍,数组结构与a一致。

#深度组合 将相同的元组作为参数传给 dstack
print(np.dstack((a, b)))
print('\n')

#列组合
print(np.column_stack((a, b)))#对于二维数组,column_stack 与hstack的效果是相同
print('\n') 
# 行组合
print(np.row_stack((a,b)))#对于二维数组,column_stack与vstack 的效果是相同

推荐收藏!2万字图解Numpy 从上可以看出,深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合,比如这里只有2个数组a和b,所以深度只有2,由于a和b都是3*3,就形成如下结果: 推荐收藏!2万字图解Numpy 二维数组中,行组合和列组合与水平组合、垂直组合一样,不作过多介绍。

4.数组的分割

数组能组合 ,当然也能分割成多个子数组。像组合一样,也可分为水平分割、垂直分割、深度分割。

1、水平分割 和垂直分割

import numpy as np  #导入numpy包,并另命令为np

a = np.array([[0, 1, 2],[3, 4, 5],[6, 7, 8]]) #定义一个多维数组
#水平分割
print(np.hsplit(a,3))  #hsplit把数组沿着水平方向分割为3个相同大小的子数组
# 或者
print(np.split(a,3,axis=1)) #同hsplit

#垂直分割
print(np.vsplit(a,3))  #vsplit把数组沿着垂直方向分割为3个相同大小的子数组
# 或者
print(np.split(a,3,axis=0)) #同vsplit,注意参数

运行结果: 推荐收藏!2万字图解Numpy 整理后,得到:[array([[0],[3],[6]]), array([[1], [4],[7]]), array([[2],[5],[8]])]也就是将0,3,6归为一组,注意:都是分别用"[ ]"和","分开的。

2、深度分割

import numpy as np  #导入numpy包,并另命令为np

c = np.array(np.arange(27).reshape(3, 3, 3))  #创建一个多维数组,并设置
print(np.dsplit(c,3)) 

运行结果如下

[array([[[ 0],[ 3],[ 6]],[[ 9],[12],[15]],[[18],[21],[24]]]),

array([[[ 1],[ 4],[ 7]],[[10],[13],[16]],[[19],[22],[25]]]),

array([[[ 2],[ 5],[ 8]],[[11],[14],[17]],[[20],[23],[26]]])

]

生成的C数组为 : 推荐收藏!2万字图解Numpy 这三块数据应该像纸张一样叠加的,0,3,6的下一层对应的是9,12,15,再下一层是18,21,24。

5.Numpy数组的其他属性

在开始的代码中有 .dtype和 .shape分别是数组的两个不同的属性,除此之外,还有其他属性,如下:

import numpy as np  #导入numpy包,并另命令为np

a = np.array([[0, 1, 2],[3, 4, 5],[6, 7, 8]]) #定义一个多维数组
print(a.dtype)    #数组a的数据类型
print(a.shape)    #数组a的维数
print(a.ndim)     #给出数组的维数,或数组轴的个数
print(a.size)     #给出数组元素的总个数
print(a.itemsize) #元素在内存中所占的字节数
print(a.nbytes)   #元素在内存中所占的存储空间,itemsize和size属性值的乘积

#复数的表示
b =  np.array([1.j + 1, 2.j + 3])
print(b.real)#打印实数
print(b.imag)#打印虚数部分

c = np.arange(4).reshape(2,2)

print(c)

f = c.flat   #flat属性,可以像遍历一维数组一样去遍历任意的多维数组
for item in f :
    print(item)
    
#或者获取多个元素
print( c.flat[[1,3]])
#flat 属性是一个可赋值的属性。对flat属性赋值将导致整个数组的元素都被覆盖
c.flat=5   # 对flat属性赋值将导致整个数组的元素都被覆盖
print(c)

b =  np.array([1.j + 1, 2.j + 3])  # 数组的转换
print( b.tolist())

print( b.astype(int)) #astype 函数可以在转换数组时指定数据类型int

运行结果如下: 推荐收藏!2万字图解Numpy 小结:

上述列举了许多有关NumPy的基础知识:数据类型和NumPy数组。类似于Python列表,NumPy数组也可以方便地进行切片和索引操作。但在多维数组上,NumPy有明显的优势。

对涉及改变数组维度的操作有很多种——组合、调整、设置维度和分割等,列举了实用函数进行了说明。

二丶 Numpy常用函数介绍

摘要:本篇我们将以分析历史股价为例,介绍怎样从文件中载入数据,以及怎样使用NumPy的基本数学和统计分析函数、学习读写文件的方法,并尝试函数式编程和NumPy线性代数运算,来学习NumPy的常用函数。

1.文件读入 :读写文件是数据分析的一项基本技能

CSV(Comma-Separated Value,逗号分隔值)格式是一种常见的文件格式。通常,数据库的转存文件就是CSV格式的,文件中的各个字段对应于数据库表中的列。

NumPy中的 loadtxt 函数可以方便地读取CSV文件,自动切分字段,并将数据载入NumPy数组。

1、保存或创建新文件

import numpy as np

i = np.eye(3) #eye(n)函数创建n维单位矩阵
print(i)
np.savetxt('test.txt', i) #savetxt()创建并保存test.txt文件

savetxt()函数,如果有已经文件则更新,如目录中没有,则创建并保存test.txt文件

运行结果如下:

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

2、读取csv文件的函数loadtxt

1)先在保存程序的目录下创建一个名称为data.csv的文件,并设置数据如下图: 推荐收藏!2万字图解Numpy

2)读取文件,如下:

c,v=np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True)

usecols 的参数是一个元组,以获取第7字段至第8字段的数据,也就是上述文件中 股票的收盘价和成交量数据。 unpack 参数设置为 True ,是分拆存储不同列的数据,即分别将收盘价和成交量的数组赋值给变量c和v。

3、常见的函数

成交量加权平均、时间加权、算术平均值、中位数、方差等

import numpy as np

i = np.eye(3) #eye(n)函数创建n维单位矩阵
print(i)
np.savetxt('test.txt', i) #savetxt创建并保存test.txt文件

#读取csv文件
c,v=np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True)
"""usecols 的参数为一个元组,以获取第7字段至第8字段的数据,也就是股票的收盘价和成交量数据。 unpack 参数设置为 True ,是分拆存储不同列的数据,即分别将收
盘价和成交量的数组赋值给变量c和v"""
vwap = np.average(c, weights=v)  #调用了average函数,将v作为权重参数使用,
print(vwap)
print('\n')
print( np.mean(c)) #算术平均值
print('\n')
t = np.arange(len(c))
print( t )
print('\n')
twap =np.average(c, weights=t) #按时间权重
print( twap )
print('\n')
h,l=np.loadtxt('data.csv',delimiter=',', usecols=(4,5), unpack=True)
# 获取第4字段至第5字段的数据,即股票的最高价和最低价

print ( np.max(h)) #获取最大值max()
print ( np.min(l)) #获取最小值min()
print('\n')
print( np.ptp(h) ) # 用ptp()函数计算了极差,即最大值和最小值之间的差值
print( np.ptp(l) )
print('\n')
print( np.median(c)) # 中位数median()函数,即多个数据中,处于中间的数
print( np.msort(c))#msort(( ))函数对价格数组进行排序,可以验证上述中位数
#方差的计算
variance = np.var(c) #方差函数var()
print(variance)

用代码、excel进行相关计算,运行结果如下: 推荐收藏!2万字图解Numpy 为后面计算,将data.csv中的数据多增加几行,修改如下并保存(为后面日期读写与修改,日期形式修改成如下):

603112,2022-4-1,,13.56,13.97,13.55,13.87,3750000
603112,2022-4-2,,13.75,14.25,13.69,14.03,4003500
603112,2022-4-3,,13.69,14.11,13.61,13.95,3956500
603112,2022-4-4,,14.3,14.3,13.73,13.89,4250000
603112,2022-4-5,,14.1,14.5,13.93,14,4013500
603112,2022-4-6,,14.5,15.4,14.35,15.4,9056500
603112,2022-4-7,,16,16.94,15.85,16.94,3750000

4、股票的收益率等

股市中最常见的就是涨幅,也就是今日收盘价相对昨日涨跌的比例,即 (今日收盘价-昨天收盘价)/昨日收盘价*100,numpy中的 diff() 函数可以返回一个由相邻数组元素的差值构成的数组,由于相邻数据相减,因此diff()数组数据较原数组少一个。

如上述修改后,有7天的收盘价,diff()计算出的结果就只有6位,

import numpy as np

#读取csv文件
c,v=np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True)

#股票的简单收益率
# diff 函数可以返回一个由相邻数组元素的差值构成的数组
results = np.diff(c)
print(results)
print('\n')
results1 = np.diff(c)/c[:-1]*100  #相对前一天的涨幅
print(results1)
print('\n')
Standard_deviation =np.std(results) # 计算出标准差
print(Standard_deviation)

运行结果,代码、excel进行相比较: 推荐收藏!2万字图解Numpy 5、对数收益与波动率

1)对数收益:log 函数得到每一个收盘价的对数,再对结果使用 diff 函数即可,

logreturns = np.diff( np.log(c) )
print(logreturns)

运行结果:

[ 0.01146966 -0.00571839 -0.00431035  0.00788817  0.09531018  0.09531018]
  1. where的作用

where 函数可以根据指定的条件返回所有满足条件的序列索引值,比如上述logreturns中有两个小于0的数据。

posretindices = np.where(results1 > 0) 
print('Indices with positive returns1',posretindices)

运行结果:

Indices with positive returns1 (array([0, 3, 4, 5], dtype=int64),)

3)波动率:波动率=对数收益率的标准差除以其均值,再除以交易周期倒数的平方根。下面代码分别为以年、月进行统计的波动率.

annual_volatility =(np.std(logreturns)/np.mean(logreturns))/np.sqrt(1./252.)#使用浮点数才能得到正确的结果
print ( annual_volatility )
#月波动率
month_volatility =(np.std(logreturns)/np.mean(logreturns))/np.sqrt(1./12.)
print ( month_volatility )

6、日期分析

处理日期总是很烦琐。NumPy是面向浮点数运算的,因此需要对日期做一些专门的处理。

通过上述代码,我们知道,修改函数np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True)中的参数 usecols=(6,7)就可以读取不同的列,日期是在第2列,即下标应该为1(数列下标是从0开始的),可以重新定义新日期数列并获取后存入。

代码如下:

dates, c=np.loadtxt('data.csv', delimiter=',', usecols=(1,6), unpack=True) #读取下标为1、6的数据,分别存入到dates和c数列中。

但实际运行过程中会报错, 推荐收藏!2万字图解Numpy

代码需要作如下修改:

import numpy as np
from datetime import datetime

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()  
#decode('ascii') 将字符串s转化为ascii码

#读取csv文件
dates,close=np.loadtxt('data.csv',delimiter=',', usecols=(1,6),converters={1:datestr2num},unpack=True)
print(dates)

运行结果:[4. 5. 6. 0. 1. 2. 3.],也是从0开始,到6结束。为了更好地说明数据,可以采用真实的数据,即从通信达软件直接下载真实的交易数据,如下图所示: 推荐收藏!2万字图解Numpy (注意:较原来少了一列空格列)

修改代码如下:

import numpy as np
from datetime import datetime

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()  
#decode('ascii') 将字符串s转化为ascii码

#读取csv文件
dates,c=np.loadtxt('data.csv',delimiter=',', usecols=(1,5),
                       converters={1:datestr2num},unpack=True)
print(dates)

print(len(dates)) #统计导出的天数

运行结果: 推荐收藏!2万字图解Numpy 如上图,导出有420天数据。

按周一到周五,统计相关数据:

averages = np.zeros(5) #创建包含5个元素的数组,保存交易日收盘价,0-4分别代表周一到周五五个交易日
for i in range(5):  #遍历0到4的日期标识
    indices =np.where(dates==i)   #where函数得到各工作日的索引值并存储在 indices 数组
    prices=np.take(c,indices)   #take函数获取各个工作日的收盘价。
    avg= np.mean(prices) #每个工作日计算出平均值存放在 averages 数组
    averages[i] = avg  #每个工作日计算出平均值存放在 averages 数组
    print('day', i)
    #print('prices', prices)
    print("Average", avg)

print(averages)

当然除了上述外,还可以求得420天里的最大值、最小值以及交易日平均值中最大值、最小值等,对代码进行如下修:

import numpy as np
from datetime import datetime

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()  
#decode('ascii') 将字符串s转化为ascii码

#读取csv文件
dates,c=np.loadtxt('data.csv',delimiter=',', usecols=(1,5),
                       converters={1:datestr2num},unpack=True)

averages = np.zeros(5) #创建包含5个元素的数组,保存交易日收盘价,0-4分别代表周一到周五五个交易日
for i in range(5):  #遍历0到4的日期标识
    indices =np.where(dates==i)   #where函数得到各工作日的索引值并存储在 indices 数组
    prices=np.take(c,indices)   #take函数获取各个工作日的收盘价。
    avg= np.mean(prices) 
    averages[i] = avg  #每个工作日计算出平均值存放在 averages 数组,共有5个数值
    print('day', i)
    #print('prices', prices)
    print("Average", avg)

print(averages)
print('\n')

print('the top close price:',np.max(c)) #最高收盘价
print('the low close price:',np.min(c)) #最低收盘价
print('\n')

top = np.max(averages)  #找出averages数列中的最大值
print ("Highest average", top)
print ("Top day of the week", np.argmax(averages)) #argmax函数返回的是averages数组中最大元素的索引值
print('\n')

bottom = np.min(averages) #找出averages数列中的最小值
print ("Lowest average", bottom)
print ( "Bottom day of the week", np.argmin(averages))#argmin函数返回的是averages数组中最小元素的索引值

运行结果如下: 推荐收藏!2万字图解Numpy 本篇初步导入了真实的股票交易信息,并利用numpy常见函数对进行了初步的计算,列举了下列常用函数:

loadtxt() 函数可以方便地读取CSV文件,自动切分字段,并将数据载入NumPy数组。

savetxt()创建并保存test.txt文件

np.loadtxt('data.csv', delimiter=',', usecols=(6,7),)usecols参数用来选择读取的数列

np.average(c, weights=v) 加权平均,将v作为权重参数使用,

np.mean(c)) #算术平均值

np.max(h))#获取最大值max()

np.min(l)) #获取最小值min()

np.ptp(h) ) ptp()函数计算了极值差

np.median(c)) 中位数median()函数,即多个数据中,处于中间的数

np.msort(c))函数对价格数组进行排序,

np.var(c) 方差函数var()

np.diff(c) 函数可以返回一个由相邻数组元素的差值构成的数组

np.std(results) # 标准差

np.diff( np.log(c) )

np.where(results1 > 0) 选择

np.sqrt()#平方根sqrt(),浮点数

s.decode('ascii') 将字符串s转化为ascii码

np.take(c,indices) #take函数获取各个工作日的收盘价。

np.argmax(averages)) #argmax函数返回数组中最大元素的索引值

np.argmin(averages))#argmin函数返回数组中最小元素的索引值

三丶Numpy常用函数介绍(3)

摘要:先汇总相关股票价格,然后有选择地对其分类,再计算移动均线、布林线等。

1.汇总数据

汇总整个交易周中从周一到周五的所有数据(包括日期、开盘价、最高价、最低价、收盘价,成交量等),由于我们的数据是从2020年8月24日开始导出,数据多达420条,先截取部分时间段的数据,不妨先读取开始20个交易日的价格。代码如下:

import numpy as np
from datetime import datetime

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()
#decode('ascii') 将字符串s转化为ascii码

#读取csv文件 ,将日期、开盘价、最低价、最高价、收盘价、成交量等全部读取
dates, opens, high, low, close,vol=np.loadtxt('data.csv',delimiter=',', usecols=(1,2,3,4,5,6),converters={1:datestr2num},unpack=True) #按顺序对应好data.csv与usecols=(1,2,3,4,5,6)中的列#获取20个交易日的数据 closes = close[0:20] #实际存取下标是0-19 dateslist = dates[0:20] print(closes) #打印出closes数列 print(dateslist)

这样就把data.csv中对应的日期、开盘价、最高价、最低价、收盘价,成交量等分别存入到dates, opens, high, low, close,vol中。由于后面示例只统计20个交易日数据,所以closes = close[0:20] ,即截取close中前20个数据。

运行结果:

37.5  37.58 37.23 36.9  38.45 37.69 37.42 37.2  36.98 36.8  36.79 37.59 37.6  37.7  37.24 37.35 37.9  38.06 37.87 38.99]
[0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4.]

即20个交易日的收盘价和所属的星期(0表示周一、4表示周五)。

分别看一下最开始周一的下标和最后一个周五的下标

first_monday = np.ravel(np.where(dateslist == 0))[0]
print ("The first Monday index is", first_monday)
#返回最后一个周五的位置
last_friday = np.ravel(np.where(dateslist == 4))[-1]
print ("The last Friday index is", last_friday)
print('\n')

运行结果:

The first Monday index is 0
The last Friday index is 19

定义一个数组,用于存储20个交易日的索引值

weeks_indices = np.arange(first_monday, last_friday+1)
print ("Weeks indices initial", weeks_indices)

按5个交易日,分成4周,对20个交易日分成4周:

weeks_indices = np.split(weeks_indices,4)
print("Weeks indices after split", weeks_indices)
Weeks indices initial [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
Weeks indices after split [array([0, 1, 2, 3, 4], dtype=int64), array([5, 6, 7, 8, 9], dtype=int64), array([10, 11, 12, 13, 14], dtype=int64), array([15, 16, 17, 18, 19], dtype=int64)]

NumPy中,数组的维度也被称作轴。apply_along_axis 函数会调用另外一个由我们给出的函数,作用于每一个数组元素上,数组中有4个元素,分别对应于示例数据中的4个星期,元素中的索引值对应于示例数据中的1天。在调用apply_along_axis 时提供我们自定义的函数名summarize,并指定要作用的轴或维度的编号(如取1)、目标数组以及可变数量的summarize函数的参数,同时进行保存。

# 定义一个函数,该函数将为每一周的数据返回一个元组,包含这一周的开盘价、最高价、最低价和收盘价,类似于每天的盘后数据def summarize(a, o, h, l, c):     monday_open = o[a[0]] #周一开盘价
    week_high = np.max( np.take(h, a) ) # 某周最高价
    week_low = np.min( np.take(l, a) )  # 某周最低价
    friday_close = c[a[-1]]      #某周的收盘价
    
    return("招商银行", monday_open, week_high, week_low, friday_close) #返回某周开盘、最高、低价、收盘价

weeksummary = np.apply_along_axis(summarize, 1, weeks_indices,opens, high, low, close)
print ("Week summary", weeksummary)

np.savetxt("weeksummary.csv", weeksummary, delimiter=",", fmt="%s")

实际运行如下: 推荐收藏!2万字图解Numpy

2.均线

1、波动幅度均值(ATR) ATR(Average True Range,真实波动幅度均值)是一个用来衡量股价波动性的技术指标。ATR是基于N个交易日的最高价和最低价进行计算的,通常取最近20个交易日。

(1) 前一个交易日的收盘价。 previousclose = c[-N -1: -1]

对于每一个交易日,计算以下各项。 h – l 当日最高价和最低价之差。   h – previousclose 当日最高价和前一个交易日收盘价之差。    previousclose – l 前一个交易日收盘价和当日最低价之差。

(2) 用NumPy中的 maximum 函数返回上述三个中的最大值。 truerange = np.maximum(h - l, h - previousclose, previousclose - l)

(3) 创建一个长度为 N 的数组 atr ,并初始化数组元素为0。atr = np.zeros(N)

(4) 这个数组的首个元素就是 truerange 数组元素的平均值。atr[0] = np.mean(truerange)

5)计算出每个交易日的波动幅度:

for i in range(1, N):
atr[i] = (N - 1) * atr[i - 1] + truerange[i]
atr[i] /= N

示例代码如下:

import numpy as np
from datetime import datetime

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

dates, opens, high, low, close,vol=np.loadtxt('data.csv',delimiter=',', usecols=(1,2,3,4,5,6),
                       converters={1:datestr2num},unpack=True)
closes = close[0:20]  #实际存取下标是0-19
dateslist = dates[0:20]
first_monday = np.ravel(np.where(dateslist == 0))[0]
last_friday = np.ravel(np.where(dateslist == 4))[-1]#从最后一个位置开始
weeks_indices = np.split(np.arange(first_monday, last_friday+1),4)

#波动幅度均值(ATR)
N = 20
h = high[-N:]
l = low[-N:]

print ("len(high)", len(h), "len(low)", len(l))
#print ("Close", close)
#前一日的收盘价数列
previousclose = close[-N-1: -1]
print ("len(previousclose)", len(previousclose))
print ("Previous close", previousclose)

#用NumPy中的maximum函数,在 最高-最低,最高-昨日收盘,昨日收盘 三个数据选择最大
truerange = np.maximum(h-l,h-previousclose,previousclose) 
print ("True range", truerange)

atr = np.zeros(N)  # 创建一个长度为 N 的数组 atr ,并初始化数组元素为0
atr[0] = np.mean(truerange) # 数组的首个元素设定为truerange数组元素的平均值
for i in range(1, N):  #循环,计算每个交易日的波幅,并保存
    atr[i] = (N - 1) * atr[i - 1] + truerange[i] 
    atr[i] /= N
print ("ATR", atr)

运行结果:

len(high) 20 len(low) 20
len(previousclose) 20
Previous close [42.1  41.1  41.28 42.5  38.83 38.41 38.04 39.62 39.93 39.26 37.91 36.47 36.98 37.21 36.61 37.15 36.89 38.6  38.5  38.03]
True range [1.08 1.5  2.32 2.23 1.56 1.02 2.13 1.49 1.16 0.85 1.67 1.9  0.96 0.63 0.99 0.69 1.74 1.18 0.73 2.15]
ATR [1.399      1.40405    1.4498475  1.48885513 1.49241237 1.46879175 1.50185216 1.50125955 1.48419658 1.45248675 1.46336241 1.48519429 1.45893458 1.41748785 1.39611345 1.36080778 1.37976739 1.36977902 1.33779007 1.37840057]

推荐收藏!2万字图解Numpy 2、移动均线:股市中最常见的是指标,移动平均线只需要少量的循环和均值函数即可计算得出。简单移动平均线是计算与等权重的指示函数的卷积。

简单移动平均线(simple moving average)通常用于分析时间序列上的数据。我们按照时间序列,并N个周期数据的均值。

(1) 使用 ones 函数创建一个长度为 N 的元素均初始化为1的数组,然后对整个数组除以 N ,即可得到权重,比如 5日均线,即N=5,则平均每天的权重都为0.2.

N = 5
weights = np.ones(N) / N
print ("Weights", weights)

(2)使用 convolve 函数调用上述的权重值

sma = np.convolve(weights, c)[N-1:-N+1]

从 convolve 函数返回的数组中,取出中间的长度为N的部分,下面的代码将创建 一个存储时间值的数组

N = 5
weights = np.ones(N) / N
print ("Weights", weights)

sma = np.convolve(weights, close)[N-1:-N+1]
print(sma)
print(len(sma))

运行结果如下,可以看到,导出的420个数据,通过计算,得到的均线数组有416个。 推荐收藏!2万字图解Numpy 很明显sma是一个数列,用前期matplotlib中的函数,可以绘制画面,增加如下代码:

import matplotlib.pyplot as plt
#省略上述代码

plt.plot(sma, linewidth=5)

运行结果如下: 推荐收藏!2万字图解Numpy

3、指数移动平均线

指数移动平均线(exponential moving average)是另一种技术指标。指数移动平均线使用的权重是指数衰减的。对历史数据点赋予的权重以指数速度减小,但不会到达0。在计算权重的过程中使用 exp 和 linspace 函数。

1)先了解numpy中的exp 和 linspace 函数

x = np.arange(5)
y = np.arange(10)
print ("Exp", np.exp(x)) # exp 函数可以计算出每个数组元素的指数
print ("Exp", np.exp(y)) 

运行结果

ExpX [ 1.          2.71828183  7.3890561  20.08553692 54.59815003]
ExpY [1.00000000e+00 2.71828183e+00 7.38905610e+00 2.00855369e+01 5.45981500e+01 1.48413159e+02 4.03428793e+02 1.09663316e+03 2.98095799e+03 8.10308393e+03]

可以看出,exp()函数接受一个数列,计算出每个数组元素的指数。

print( "Linspace", np.linspace(-1, 0, 5))

运行结果:

Linspace [-1.   -0.75 -0.5  -0.25  0.  ]

linspace中有三个参数,其中前2个是一个范围:一个起始值和一个终止值参数,后一个是生成的数组元素的个数。

2)计算指数移动平均线

利用上述两个函数对权重进行计算:weights = np.exp(np.linspace(-1. , 0. , N))

全部代码如下:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

dates, opens, high, low, close,vol=np.loadtxt('data.csv',delimiter=',', usecols=(1,2,3,4,5,6),
                       converters={1:datestr2num},unpack=True)

N = 5
"""
weights = np.ones(N) / N
print ("Weights", weights)
sma = np.convolve(weights, close)[N-1:-N+1]
print(sma)
print(len(sma))
plt.plot(sma, linewidth=5)
"""
weights = np.exp(np.linspace(-1., 0., N)) # 
weights /= weights.sum()  #对权重值做归一化处理
print( "Weights", weights)
ema = np.convolve(weights, close)[N-1:-N+1]
#print(ema)

t = np.arange(N - 1, len(close))
plt.plot (t, close[N-1:], lw=1.0)  #收盘价绘制曲线图
plt.plot (t, ema, lw=2.0)   #按权重计算均线曲线图
plt.show()

运行结果: 推荐收藏!2万字图解Numpy

4、绘制布林带

布林带,是一个N个周期移动均线,和2倍的N周期标准差与移动均线形成的上、下形成的三条曲线。

上轨道: ema+2*np.std(close) (当然,ema也可以换成上述的sma,也可以换成close等)

移动均线:ema

下轨道: ema-2*np.std(close)

完整代码:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

dates, opens, high, low, close,vol=np.loadtxt('data.csv',delimiter=',', usecols=(1,2,3,4,5,6),
                       converters={1:datestr2num},unpack=True)

N = 5
weights = np.ones(N) / N
sma = np.convolve(weights, close)[N-1:-N+1]
deviation = []

clegth = len(close)
for i in range(N - 1, clegth ):
    if i + N < clegth :
        dev = close [i: i + N]
    else:
        dev = close [-N:]
    
    averages = np.zeros(N)
    averages.fill(sma[i - N - 1]) #fill()函数可以用一个指定的标量值填充数组,而这个标量值也是 fill 函数唯一的参数。
    dev = dev - averages
    dev = dev ** 2
    dev = np.sqrt(np.mean(dev))
    deviation.append(dev) 

deviation = 2 * np.array(deviation)
upperBB = sma + deviation
lowerBB = sma - deviation

c_slice = close[N-1:]
between_bands = np.where((c_slice < upperBB) & (c_slice > lowerBB))
between_bands = len(np.ravel(between_bands))
print( "Ratio between bands", float(between_bands)/len(c_slice))

t = np.arange(N-1,clegth)
plt.plot(t, c_slice, lw=1.0) #收盘价
plt.plot(t, sma, lw=2.0)     #移动均线
plt.plot(t, upperBB, lw=3.0) #上轨道
plt.plot(t, lowerBB, lw=1.0) #下轨道
plt.show()

运行结果: 推荐收藏!2万字图解Numpy

四丶Numpy常用函数介绍(4)--Numpy中的线性关系和数据修剪压缩

要:总结股票均线计算原理--线性关系,也是以后大数据处理的基础之一,NumPy的 linalg 包是专门用于线性代数计算的。作一个假设,就是一个价格可以根据N个之前的价格利用线性模型计算得出。

前一篇,在计算均线,指数均线时,分别计算了不同的权重,比如 推荐收藏!2万字图解Numpy 推荐收藏!2万字图解Numpy 都是按不同的计算方法来计算出相关的权重,一个股价可以用之前股价的线性组合表示出来,也即,这个股价等于之前的股价与各自的系数相乘后再做加和的结果,但是,这些系数是需要我们来确定的,也即一个线性相关的权重。

1.用线性模型预测价格

创建步骤如下: 1)先获取一个包含N个收盘价的向量(数组):

N=10
#N=len(close)
new_close = close[-N:]
new_closes= new_close[::-1]
print (new_closes)

运行结果:

[39.96 38.03 38.5  38.6  36.89 37.15 36.61 37.21 36.98 36.47]

2)初始化一个N×N的二维数组 A ,元素全部为 0

A = np.zeros((N, N), float)
print ("Zeros N by N", A)

3)用数组new_closes的股价填充数组A

for i in range(N):
    A[i,] = close[-N-i-1: -1-i]
print( "A", A)

试一下运行结果,并观察填充后的数组A 推荐收藏!2万字图解Numpy

4)选取合适的权重

Weights [0.11405072 0.14644403 0.18803785 0.24144538 0.31002201]和The weights : [0.2 0.2 0.2 0.2 0.2]哪一种权重更合理?用线性代数的术语来说,就是解一个最小二乘法的问题。

要确定线性模型中的权重系数,就是解决最小平方和的问题,可以使用 linalg包中的 lstsq 函数来完成这个任务

(x, residuals, rank, s) = np.linalg.lstsq(A,new_closes)

其中,x是由A,new_closes通过np.linalg.lstsq()函数,即生成的权重(向量),residuals为残差数组、rank为A的秩、s为A的奇异值。

5)预测股价,用NumPy中的 dot()函数计算系数向量与最近N个价格构成的向量的点积(dot product),这个点积就是向量new_closes中价格的线性组合,系数由向量 x 提供

print( np.dot(new_closes, x))

完整代码如下:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

dates, opens, high, low, close,vol=np.loadtxt('data.csv',delimiter=',', usecols=(1,2,3,4,5,6),
                       converters={1:datestr2num},unpack=True)

N=10
#N=len(close)
new_close = close[-N:]
new_closes= new_close[::-1]

A = np.zeros((N, N), float)

for i in range(N):
    A[i,] = close[-N-i-1: -1-i]
    
print( "A", A)

(x, residuals, rank, s) = np.linalg.lstsq(A,new_closes)
print(x) #权重系数向量 

print('\n')
print(residuals)  #残差数组
print('\n')
print(rank) #A的秩
print(s)
print('\n')#奇异值
print( np.dot(new_closes, x))

运行结果如下: 推荐收藏!2万字图解Numpy

2.趋势线

趋势线,是根据股价走势图上很多所谓的枢轴点绘成的曲线。描绘价格变化的趋势。可以让计算机来用非常简易的方法来绘制趋势线

(1) 确定枢轴点的位置。假定枢轴点位置 为最高价、最低价和收盘价的算术平均值。pivots = (high + low + close ) / 3

从枢轴点出发,可以推导出股价所谓的阻力位和支撑位。阻力位是指股价上升时遇到阻力,在转跌前的最高价格;支撑位是指股价下跌时遇到支撑,在反弹前的最低价格(阻力位和支撑位并非客观存在,它们只是一个估计量)。基于这些估计量,就可以绘制出阻力位和支撑位的趋势线。我们定义当日股价区间为最高价与最低价之差

(2) 定义一个函数用直线 y= at + b 来拟合数据,该函数应返回系数 a 和 b,再次用到 linalg 包中的 lstsq 函数。将直线方程重写为 y = Ax 的形式,其中 A = [t 1] , x = [a b] 。使用 ones_like 和 vstack 函数来构造数组 A

numpy.ones_like(a, dtype=None, order='K', subok=True) 返回与指定数组具有相同形状和数据类型的数组,并且数组中的值都为1。

numpy.vstack(tup) [source] 垂直(行)按顺序堆叠数组。 这等效于形状(N,)的1-D数组已重塑为(1,N)后沿第一轴进行concatenation。 重建除以vsplit`的数组。如下两小例:

>>> a = np.array([1, 2, 3]) 
>>> b = np.array([2, 3, 4]) 
>>> np.vstack((a,b)) 
array([[1, 2, 3],        
       [2, 3, 4]])
>>> a = np.array([[1], [2], [3]]) 
>>> b = np.array([[2], [3], [4]]) 
>>> np.vstack((a,b)) 
array([[1],
       [2],   
       [3], 
       [2],
       [3], 
       [4]])

完整代码如下:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

dates, opens, high, low, close,vol=np.loadtxt('data.csv',delimiter=',', usecols=(1,2,3,4,5,6),
                       converters={1:datestr2num},unpack=True)
"""
N=10
#N=len(close)
new_close = close[-N:]
new_closes= new_close[::-1]


A = np.zeros((N, N), float)

for i in range(N):
    A[i,] = close[-N-i-1: -1-i]
   
print( "A", A)
(x, residuals, rank, s) = np.linalg.lstsq(A,new_closes)
print(x) #权重系数向量 
print(residuals)  #残差数组
print(rank) #A的秩
print(s)
print( np.dot(new_closes, x))
"""
pivots = (high + low + close ) / 3

def fit_line(t, y):
    A = np.vstack([t, np.ones_like(t)]).T
# np.ones_like(t) 即定义一个像t一样,有相同形状和数据类型的数组,并且数组中的值都为1 
    return np.linalg.lstsq(A, y)[0]

t = np.arange(len( close)) #按close数列创建一个数列t

sa, sb = fit_line(t, pivots - (high - low)) #用直线y=at+b来拟合数据,该函数应返回系数a(sa) 和 b(sb)
ra, rb = fit_line(t, pivots + (high - low))
support = sa * t + sb     #计算支撑线数列
resistance = ra * t + rb  #计算阻力线数列

condition = (close > support) & (close < resistance)#设置一个判断数据点是否位于趋势线之间的条件,作为 where 函数的参数
between_bands = np.where(condition)

plt.plot(t, close,color='r')
plt.plot(t, support,color='g')
plt.plot(t, resistance,color='y')
plt.show()

运行结果: 推荐收藏!2万字图解Numpy

3.数组的修剪和压缩

NumPy中的 ndarray 类定义了许多方法,可以对象上直接调用。通常情况下,这些方法会返回一个数组。

ndarray 对象的方法相当多,像前面遇到的 var 、 sum 、 std 、 argmax 、argmin 以及 mean 函数也均为 ndarray 方法。下面介绍一下数组的修前与压缩。

1、 clip 方法返回一个修剪过的数组:将所有比给定最大值还大的元素全部设为给定的最大值,而所有比给定最小值还小的元素全部设为给定的最小值

a = np.arange(10)
print("a =", a)
print("Clipped", a.clip(3, 7))

运行结果:

a = [0 1 2 3 4 5 6 7 8 9]
Clipped [3 3 3 3 4 5 6 7 7 7]

很明显,a.clip(3,7)将数组a中的小于3的设置为3,大于7的全部设置为7.

2、 compress 方法返回一个根据给定条件筛选后的数组

b = np.arange(10)
print (a)
print ("Compressed", a.compress(a >3))

运行结果:

[0 1 2 3 4 5 6 7 8 9]
Compressed [4 5 6 7 8 9]

4.阶乘

prod() 方法,可以计算数组中所有元素的乘积.

c = np.arange(1,5)
print("b =", c)
print("Factorial", c.prod())

运行结果:

b = [1 2 3 4]
Factorial 24

如果想知道1~8的所有阶乘值,调用 cumprod()方法,计算数组元素的累积乘积。

print( "Factorials", c.cumprod())

运行结果:

Factorials [  1   2   6  24 120]

推荐收藏!2万字图解Numpy 本篇主要介绍了一个通过现在有数据,用函数 y= at + b 来拟合数据进行线性拟合后,用 linalg包中的 lstsq 函数来完成最小二乘相关后,预测股价的实例,来了解了一些numpy的函数及作用;同时介绍 了数据修剪及压缩和阶乘的计算。

五丶Numpy常用函数介绍(5)--Numpy中的相关性函数

摘要:NumPy中包含大量的函数,这些函数的设计初衷是能更方便地使用,掌握解这些函数,可以提升自己的工作效率。这些函数包括数组元素的选取和多项式运算等。下面通过实例进行详细了解。

前述通过对某公司股票的收盘价的分析,了解了某些Numpy的一些函数。通常实际中,某公司的股价被另外一家公司的股价紧紧跟随,它们可能是同领域的竞争对手,也可能是同一公司下的不同的子公司。可能因两家公司经营的业务类型相同,面临同样的挑战,需要相同的原料和资源,并且争夺同类型的客户。

实际中,有很多这样的例子,如果要检验一下它们是否真的存在关联。一种方法就是看看两个公司股票收益率的相关性,强相关性意味着它们之间存在一定的关联性(特别是当所用的数据不够充足时,误差可能更大)

1.股票相关性分析

1、导出两个相关的股票数据,如下依次为:股票代码、日期、开盘价、最高价、最低价、收盘价、成交量。 推荐收藏!2万字图解Numpy 2、分别从CSV文件中读入相关数据,即收盘价:

close = np.loadtxt('data036.csv',delimiter=',', usecols=(5,),converters={1:datestr2num},unpack=True)
new_close = np.loadtxt('data999.csv',delimiter=',', usecols=(5,),converters={1:datestr2num},unpack=True)

3、协方差描述的是两个变量共同变化的趋势,其实就是归一化前的相关系数。使用 cov 函数计算股票收益率的协方差矩阵,完整代码如下:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

close=np.loadtxt('data036.csv',delimiter=',', usecols=(5,),converters={1:datestr2num},unpack=True) #导入data036.csv数据 new_close=np.loadtxt('data999.csv',delimiter=',', usecols=(5,),converters={1:datestr2num},unpack=True)#导入data999.csv数据covariance = np.cov(close,new_close) #使用numpy.cov() 函数计算两个数列的协方差矩阵print(close.mean()) #求close的平均值print(new_close.mean())#求new_close的平均值print('covariance:','\n',covariance)

运行结果:

48.40690476190476
18.85157142857143
covariance: 
 [[30.46934553  1.5201865 ]
 [ 1.5201865   8.96031113]]

1)用 diagonal 函数查看矩阵对角线上的元素

print ("对角元素:", covariance.diagonal()) # diagonal查看对角上的元素

运行结果:

对角元素: [30.46934553  8.96031113]

2)使用 trace 函数计算矩阵的迹,即对角线上元素之和

print("Covariance trace", covariance.trace()) #对角线上元素之和

3)两个向量的相关系数被定义为协方差除以各自标准差的乘积。计算向量 a 和 b 的相关系数的公式:corr(a,b)=cov(a,b)/(std(a)*std(b))

covar = covariance/ (np.std(close) * np.std(new_close))
print("相关系数矩阵:", covar) 

运行结果:

相关系数矩阵: [[1.84843969 0.09222295]
 [0.09222295 0.54358223]]

注意:由于covariance是一个矩阵,因而得到的covar也是一个矩阵

相关系数是两只股票的相关程度。相关系数的取值范围在 -1 到 1 之间。根据定义,一组数值与自身的相关系数等于 1 ,numpy中使用 corrcoef 函数计算相关系数

closecorr = np.corrcoef(close,new_close)
print("相关系数:",'\n', closecorr ) 

运行结果:

相关系数: 
 [[1.         0.09200338]
 [0.09200338 1.        ]]

对角线上的元素即close和new_close与自身的相关系数,因此均为1。相关系数矩阵是关于对角线对称的,因此另外两个元素的值相等,表示close和new_close的相关系数等于new_close和close的相关系数。

判断两只股票的价格走势是否同步的要点是,它们的差值偏离了平均差值2倍于标准差的距离,则认为这两只股票走势不同步。代码如下:

difference = close - new_close
avg = np.mean(difference)
dev = np.std(difference)
print ("Out of sync:", np.abs(difference[-1]-avg)>2*dev)

运行结果:

Out of sync: False

2.多项式

微积分里有泰勒展开,也就是用一个无穷级数来表示一个可微的函数。实际上,任何可微的(从而也是连续的)函数都可以用一个N次多项式来估计,而比N次幂更高阶的部分为无穷小量可忽略不计。

NumPy中的 ployfit 函数可以用多项式去拟合一系列数据点,无论这些数据点是否来自连续函数都适用。

继续使用close和new_close的股票价格数据。用一个三次多项式去拟合两只股票收盘价的差价。

t = np.arange(len(close)) #得到close数列的长度
poly = np.polyfit(t, close - new_close, 3) #利用长度t和两只股票的价差,生成一个三项式,三项式有3个系数和一个常量
print("Polynomial fit", poly)

运行结果:

Polynomial fit: [ 1.61308827e-07 -4.34114354e-04  1.84480028e-01  1.33680483e+01]

用我们刚刚得到的多项式对象以及 polyval 函数,推断下一个差值:

print ("Next value:", np.polyval(poly, t[-1] + 1))  #用生成的多项式拟合求下一个差值
print(difference[-1]) #打印最后一个实际的差值

运行结果:

Next value: 26.222936287829654
26.21

在极限情况下,差值可以在某个点为0。使用 roots 函数找出拟合的多项式函数什么时候到达0值:

print( "Roots", np.roots(poly))#root返回多项式的根

运行结果:

Roots [2138.21411788  615.9134063   -62.92728874]

3.求极值的知识

极值是函数的最大值或最小值。在高等代数微积分中,这些极值点位于函数的导数为0的位置,然后再求导数函数的根,即找出原多项式函数的极值点。

1)使用 polyder 函数对多项式函数求导

der = np.polyder(poly)
print("Derivative", der)

2)求出导数函数的根,即找出原多项式函数的极值点

print( "Extremas", np.roots(der))

运行后即得到如下:

Derivative: [ 4.83926482e-07 -8.68228709e-04  1.84480028e-01]
Extremas [1547.84609151  246.28739879]

3)用 polyval 计算多项式函数的值,并用matplotlib显示

vals = np.polyval(poly, t)
print('vals:',vals)
print('max value:', np.argmax(vals))
print('min value:', np.argmin(vals))
plt.plot(t,difference)plt.plot(t,vals)plt.show()

运行结果如下: 推荐收藏!2万字图解Numpy

六丶Numpy常用函数介绍(6)--Numpy中矩阵和通用函数

在NumPy中,矩阵是 ndarray 的子类,与数学概念中的矩阵一样,NumPy中的矩阵也是二维的,可以使用 mat 、 matrix 以及 bmat 函数来创建矩阵。

1.创建矩阵

mat 函数创建矩阵时,若输入已为 matrix 或 ndarray 对象,则不会为它们创建副本。 因此,调用 mat() 函数和调用 matrix(data, copy=False) 等价。

  1. 在创建矩阵的专用字符串中,矩阵的行与行之间用分号隔开,行内的元素之间用空格隔开。使用如下的字符串调用 mat 函数创建矩阵:
import numpy as np

A = np.mat('1 2 3; 4 5 6; 7 8 9')
print("Creation from string:", A)

运行结果:

Creation from string: 
[[1 2 3]
 [4 5 6]
 [7 8 9]]

2)用T属性获取转置矩阵

print("transpose A:", A.T)  # 用T属性获取转置矩阵

3)用I属性获取逆矩阵

print("Inverse A:", A.I)  # 用I属性获取逆矩阵

4)用NumPy数组进行创建矩阵

B = np.mat(np.arange(9).reshape(3, 3))
print("Creation from array:", B)#使用NumPy数组进行创建

上述运行结果:

Creation from string: [[1 2 3]
 [4 5 6]
 [7 8 9]]
transpose A: [[1 4 7]
 [2 5 8]
 [3 6 9]]
Inverse A: [[ 3.15251974e+15 -6.30503948e+15  3.15251974e+15]
 [-6.30503948e+15  1.26100790e+16 -6.30503948e+15]
 [ 3.15251974e+15 -6.30503948e+15  3.15251974e+15]]
Creation from array: [[0 1 2]
 [3 4 5]
 [6 7 8]]

2.从已有矩阵创建新矩阵

希望利用一些已有的较小的矩阵来创建一个新的大矩阵。这可以用 bmat 函数来实现。这里的 b 表示“分块”, bmat 即分块矩阵(block matrix)。

1)先创建一个3*3的单位矩阵:

C = np.eye(3)
print("C:",C)

运行结果:

C: 
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

2)创建一个与C同型的矩阵,乘以2

D = 2 * C
print ("D:",D)

运行结果:

D: 
[[2. 0. 0.]
 [0. 2. 0.]
 [0. 0. 2.]]

3)使用字符串创建复合矩阵:

字符串的格式与 mat 函数中一致,只是在这里你可以用矩阵变量名代替数字:

print("Compound matrix\n", np.bmat("C D;C D"))

运行结果:

Compound matrix:
 [[1. 0. 0. 2. 0. 0.]
 [0. 1. 0. 0. 2. 0.]
 [0. 0. 1. 0. 0. 2.]
 [1. 0. 0. 2. 0. 0.]
 [0. 1. 0. 0. 2. 0.]
 [0. 0. 1. 0. 0. 2.]]

3.通用函数

通用函数的输入是一组标量,输出也是一组标量,它们通常可以对应于基本数学运算,如加、减、乘、除等。

1、使用NumPy中的 frompyfunc 函数,通过一个Python函数来创建通用函数,步骤如下:

1)定义一个回答某个问题的Python函数

2)用 zeros_like 函数创建一个和 a 形状相同,并且元素全部为0的数组 result

3)将刚生成的数组中的所有元素设置其值为42

2、在 add 上调用通用函数的方法

通用函数并非真正的函数,而是能够表示函数的对象。通用函数有四个方法,不过这些方法只对输入两个参数、输出一个参数的ufunc对象有效,例如 add 函数。

其他不符合条件的ufunc对象调用这些方法时将抛出 ValueError 异常。因此只能在二元通用函数上调用这些方法。以下将逐一介绍这4个方法:

reduce()accumulate()reduceat()outer()

  1. 沿着指定的轴,在连续的数组元素之间递归调用通用函数,即可得到输入数组的规约(reduce)计算结果。

对于 add 函数,其对数组的reduce计算结果等价于对数组元素求和。调用reduce 方法:

a = np.arange(9)
print("Reduce:", np.add.reduce(a)) #调用add函数的reduce方法

运行结果:

Reduce 36

2) accumulate 方法同样可以递归作用于输入数组

在 add 函数上调用 accumulate 方法,等价于直接调用 cumsum 函数。在 add 函数上调用 accumulate 方法:

print( "Accumulate", np.add.accumulate(a)) #调用add函数的accumulate方法

运行结果:

Accumulate [ 0  1  3  6 10 15 21 28 36]

3)educeat 方法需要输入一个数组以及一个索引值列表作为参数。

print ("Reduceat", np.add.reduceat(a, [0, 5, 2, 7]))

educeat 方法的作用是,在数列a中,分别计算索引间的累加,比如上述的 [0, 5, 2, 7],分别计算索引0-5,5-2(5>2,所以直接取索引为5的数据),2-7,7-(-1) 等四组序列形成的 推荐收藏!2万字图解Numpy 比如,0-5就是计算A-E列中的数据,结果为10;5-2,直接取索引为5,即F的数据5;2-7,即B-G的计算结果为20;7-(-1)即索引7到最后,也即H、I的计算结果为15。 推荐收藏!2万字图解Numpy 4)outer 方法

返回一个数组,它的秩(rank)等于两个输入数组的秩的和。它会作用于两个输入数组之间存在的所有元素对。在 add 函数上调用 outer 方法:

print("Outer:\n", np.add.outer(np.arange(3), a))

运行结果:

Outer:
 [[ 0  1  2  3  4  5  6  7  8]
 [ 1  2  3  4  5  6  7  8  9]
 [ 2  3  4  5  6  7  8  9 10]]

4.算术运算

在NumPy中,基本算术运算符+、-和 * 隐式关联着通用函数 add 、 subtract 和 multiply ,对NumPy数组使用这些算术运算符时,对应的通用函数将自动被调用。除法包含的过程则较为复杂,在数组的除法运算中涉及

三个通用函数 divide 、 true_divide 和floor_division ,以及两个对应的运算符 / 和 // 。

1、除法运算:

import numpy as np

a = np.array([2, 6, 5])
b = np.array([1, 2, 3])

print("Divide:\n", np.divide(a, b), np.divide(b, a))

除了divide()函数外,还有floor_divide(),以及运算符‘/’和‘//’,(‘/’和‘//’分别和divide和floor_divide作用一样)如下代码:

import numpy as np

a = np.array([2, 6, 5])
b = np.array([1, 2, 3])

print("Divide:\n", np.divide(a, b), np.divide(b, a))
print("True Divide:\n", np.true_divide(a, b), np.true_divide(b, a))#回除法的浮点数结果而不作截断

print("Floor Divide:\n", np.floor_divide(a, b), np.floor_divide(b, a))  #返回整数结果
c = 3.14*b
print("Floor Divide2:\n", np.floor_divide(c, b), np.floor_divide(b, c)) #返回整数结果

print( "/ operator:\n", a/b, b/a)  # "/"运算符相当于调用 divide 函数

print( "// operator:\n", a//b, b//a) #运算符//对应于floor_divide 函数
print( "// operator2:\n", c//b, b//c)

运行结果:

Divide:
 [2.         3.         1.66666667] [0.5        0.33333333 0.6       ]
True Divide:
 [2.         3.         1.66666667] [0.5        0.33333333 0.6       ]
Floor Divide:
 [2 3 1] [0 0 0]
Floor Divide2:
 [3. 3. 3.] [0. 0. 0.]
/ operator:
 [2.         3.         1.66666667] [0.5        0.33333333 0.6       ]
// operator:
 [2 3 1] [0 0 0]
// operator2:
 [3. 3. 3.] [0. 0. 0.]

2、模运算

计算模数或者余数,可以使用NumPy中的 mod 、 remainder 和 fmod 函数。当然,也可以使用 % 运算符。这些函数的主要差异在于处理负数的方式。

a = np.arange(-4, 4)
print('a:',a)
print ("Remainder", np.remainder(a, 2)) # remainder 函数逐个返回两个数组中元素相除后的余数
print ("Mod", np.mod(a, 2))  # mod 函数与 remainder 函数的功能完全一致
print ("% operator", a % 2)  # % 操作符仅仅是 remainder 函数的简写

print ("Fmod", np.fmod(a, 2))# fmod 函数处理负数的方式与 remainder 、 mod 和 % 不同

运行结果:

a: [-4 -3 -2 -1  0  1  2  3]
Remainder [0 1 0 1 0 1 0 1]
Mod [0 1 0 1 0 1 0 1]
% operator [0 1 0 1 0 1 0 1]
Fmod [ 0 -1  0 -1  0  1  0  1]

实际代码运行如下: 推荐收藏!2万字图解Numpy

七丶Numpy常用函数介绍(8)--Numpy中几中常见的图形

在NumPy中,所有的标准三角函数如sin、cos、tan等均有对应的通用函数。

1.利萨茹曲线

(Lissajous curve)利萨茹曲线是一种很有趣的使用三角函数的方式(示波器上显示出利萨茹曲线)。利萨茹曲线由以下参数方程定义:

x = A sin(at + n/2)

y = B sin(bt) 利萨茹曲线的参数包括 A 、 B 、 a 和 b 。为简单起见,我们令 A 和 B 均为1,设置的参数为 a=9 , b=8

import numpy as np
import matplotlib.pyplot as plt

A=B=1
a=9
b=8

t = np.linspace(-np.pi, np.pi, 201)  #使用linspace函数初始化变量t
x = np.sin(a * t + np.pi/2)  # sin 函数和NumPy常量 pi 计算变量 x 
y = np.sin(b * t)  # sin函数计算变量y
plt.plot(x, y)
plt.show()

运行结果: 推荐收藏!2万字图解Numpy

2.计算斐波那契数列

斐波那契数列的递推关系可以用矩阵来表示。斐波那契数列的计算等价于矩阵的连乘。可用两种方法计算了斐波那契数列

1)黄金比例计算方法,使用 rint 函数对浮点数取整但不改变浮点数类型

1,1,2,3,5,8,13,21,34,55,89,……

#   斐波那契数,用黄金分割公式或通常所说的比奈公式,加上取整函数
n = np.arange(1, 9)
sqrt5 = np.sqrt(5)
phi = (1 + sqrt5)/2 #利用根号5计算黄金比例,或者直接用phi=1+0.618 
print("比例:",phi)
print('\n')
fibonacci = np.rint((phi**n - (-1/phi)**n)/sqrt5)  #用rint()函数对浮点数取整但不改变浮点数类型
print("Fibonacci", fibonacci)

2)利用矩阵进行计算:用 matrix 函数创建矩阵

# 斐波那契数,用矩阵来表示斐波那契数列的递推关系
F = np.matrix([[1, 1], [1, 0]])
print ("8th Fibonacci:", (F ** 10)[0, 0])

运行结果:

比例: 1.618033988749895

Fibonacci [ 1.  1.  2.  3.  5.  8. 13. 21.]
8th Fibonacci: 89

3.方波

方波可以近似表示为多个正弦波的叠加。任意一个方波信号都可以用无穷傅里叶级数来表示。

需要累加很多项级数,且级数越多结果越精确,这里取 k=99(可以分别设置为9,50,1000等进行测试观察生成效果) 以保证足够的精度。绘制方波的步骤如下。

  1. 初始化 t 和 k 开始,并将函数值初始化为
m = np.linspace(-np.pi, np.pi, 201) #从 -pi 到 pi 上均匀分布的 201 个点
k = np.arange(1,99)   # k=99 以保证足够的精度,如图中的9 20 99显示的波形
k = 2 * k - 1
f = np.zeros_like(m)

2)使用 sin()求正弦函数,用sum()数计算各项级数:

for i in range(len(m)):  #使用 sin 和 sum 函数进行计算
    f[i] = np.sum(np.sin(k * m[i])/k)
f = (4 / np.pi) * f

3)绘制波形

plt.plot(t, f)
plt.show()

推荐收藏!2万字图解Numpy

4.锯齿波和三角波

锯齿波和三角波也是常见的波形。和方波类似,也可以将它们表示成无穷傅里叶级数。对锯齿波取绝对值即可得到三角波。锯齿波的无穷级数表达式如下:

import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(-np.pi, np.pi, 201)
k = np.arange(1, 99)
f = np.zeros_like(t)
for i in range(len(t)):
    f[i] = np.sum(np.sin(2 * np.pi * k * t[i])/k)

f = (-2 / np.pi) * f
plt.plot(t, f, lw=1.0)
plt.plot(t, np.abs(f), lw=2.0)
plt.show()

运行结果: 推荐收藏!2万字图解Numpy

八丶Numpy常用函数介绍(9)-- 与线性代数有关的模块linalg

numpy.linalg 模块包含线性代数的函数。使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。

1.计算逆矩阵

线性代数中,矩阵A与其逆矩阵A ^(-1)相乘后会得到一个单位矩阵I。该定义可以写为A *A ^(-1) =1。numpy.linalg 模块中的 inv 函数可以计算逆矩阵。

  1. 用 mat 函数创建示例矩阵
import numpy as np
import matplotlib.pyplot as plt

A = np.mat("0 1 2;1 0 3;4 -3 8")

2)用 inv 函数计算逆矩阵

inverse = np.linalg.inv(A)
print("inverse of A\n", inverse)

运行结果如下:

A
 [[ 0  1  2]
 [ 1  0  3]
 [ 4 -3  8]]
inverse of A
 [[-4.5  7.  -1.5]
 [-2.   4.  -1. ]
 [ 1.5 -2.   0.5]]

3)可能通过原矩阵和逆矩阵相乘的结果来验证

print ("Check\n", A * inverse) #验证计算,原矩阵和逆矩阵相乘的,单位矩阵

结果:

Check
 [[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

2.求解线性方程组

线性议程组 Ax=b

1)分另创建矩阵A和数组b

A = np.mat("1 -2 1;0 2 -8;-4 5 9") #用mat()函数创建示例矩阵
print("A\n", A)
b = np.array([0, 8, -9])

2)用solve(A, b)解出x,用dot()函数进行验证,并打印

x = np.linalg.solve(A, b)
print("Solution", x)
print("Check\n", np.dot(A , x)) #用dot()函数检查求得的解是否正确

3.特征值和特征向量

特征值(eigenvalue)即方程 Ax = ax 的根,是一个标量,特征向量是关于特征值的向量。在numpy.linalg 模块中, eigvals函数可以计算矩阵的特征值,而 eig 函数可以返回一个包含特征值和对应的特征向量的元组。

用 eigvals 函数求解特征值

用 eig 函数求解特征值和特征向量 ,如下代码:

print("Eigenvalues", np.linalg.eigvals(A))
eigenvalues, eigenvectors = np.linalg.eig(A)
print( "First tuple of eig", eigenvalues)
print(" Second tuple of eig\n", eigenvectors)

4.奇异值分解

奇异值分解,是一种因子分解运算,将一个矩阵分解为3个矩阵的乘积。奇异值分解是特征值分解一种推广。在 numpy.linalg 模块中的svd()函数可以对矩阵进行奇异值分解。该函数返回3个矩阵——U、Sigma和V,其中U和V是正交矩阵,Sigma包含输入矩阵的奇异值(计算出来结果可能是虚数)。

U, Sigma, V = np.linalg.svd(A, full_matrices=False)# 用svd() 函数分解矩阵
print ("U:",U)
print ("Sigma:",Sigma)
print ("V:", V)
print ("Product\n", U * np.diag(Sigma) * V) #用diag函数生成完整的奇异值矩阵

5.广义

pinv 函数进行求解,计算广义逆矩阵需要用到奇异值分解函数pinv(),行列式计算用np.linalg中的函数det()

#使用pinv函数计算广义逆矩阵:
A = np.mat("4 11 14;8 7 -2")
pseudoinv = np.linalg.pinv(A)
print("Pseudo inverse:\n", pseudoinv)
#计算矩阵的行列式
print("\n")
B = np.mat("3 4;5 6")
print("Determinant:", np.linalg.det(B))

全部代码如下:

import numpy as np
import matplotlib.pyplot as plt

A = np.mat("0 1 2;1 0 3;4 -3 8")  #用mat()函数创建示例矩阵
print ("A\n",A)
inverse = np.linalg.inv(A)  #用inv()函数计算逆矩阵
print("inverse of A\n", inverse)
print ("Check\n", A * inverse) #验证计算,原矩阵和逆矩阵相乘的,单位矩阵
#  求解线性方程组
A = np.mat("1 -2 1;0 2 -8;-4 5 9") #用mat()函数创建示例矩阵
b = np.array([0, 8, -9])
x = np.linalg.solve(A, b)
print("Solution", x)
print("Check\n", np.dot(A , x))  #用dot()函数检查求得的解是否正确
#特征值和特征向量

print("Eigenvalues", np.linalg.eigvals(A))   #eigvals函数可以计算矩阵的特征值
eigenvalues, eigenvectors = np.linalg.eig(A) #用 eig 函数求解特征值和特征向量
print( "First tuple of eig", eigenvalues)
print(" Second tuple of eig\n", eigenvectors)

#奇异值分解
U, Sigma, V = np.linalg.svd(A, full_matrices=False)# 用svd() 函数分解矩阵
print ("U:",U)
print ("Sigma:",Sigma)
print ("V:", V)
print ("Product\n", U * np.diag(Sigma) * V) #用diag函数生成完整的奇异值矩阵
#使用pinv函数计算广义逆矩阵:
A = np.mat("4 11 14;8 7 -2")
pseudoinv = np.linalg.pinv(A)
print("Pseudo inverse:\n", pseudoinv)
#计算矩阵的行列式
print("\n")
B = np.mat("3 4;5 6")
print("Determinant:", np.linalg.det(B))

运行结果: 推荐收藏!2万字图解Numpy

关注公众号:Python技术训练营

解锁 《python百万字教程,手把手助你从零进阶拿高薪》,让学习更贴近未来实战

内容包含

python百万字教程,手把手助你从零进阶拿高薪(十一模块)

1.hello,初识python

2.python大数据技术体系

3.AI研发,快人一步

4.全栈开发体系,你不能错过的内容

5.掌握核心,python核心编程

6.python并发编程

7.python数据库编程

8.爬虫入门必学

9.python框架源码分析

10.爬虫必备JS逆向

11.多学一点,加薪更稳定Android逆向

整理不易,关注一下吧ღ( ´・ᴗ・` )比心🤔

转载自:https://juejin.cn/post/7226955404926894135
评论
请登录