zoukankan      html  css  js  c++  java
  • python(5):scipy之numpy介绍

    python 的scipy 下面的三大库: numpy, matplotlib, pandas

    scipy 下面还有linalg 等

    scipy 中的数据结构主要有三种: ndarray(n维数组), Series(变长字典), Dataframe(数据框)

    numpy有强大的ndarray对象和ufunc(universal function 通用函数), 适合线性代数, 随机数处理等科学计算

    Pandas 具有高效的 Series(变长字典), Dataframe(数据框) 数据结构

    下面学习numpy

    list ,tuple 也可以表示数组 

    一维: [1,2,3];   二维数组: [[1,2,], [3,4]]

    由于列表的元素可以是任何类型, 因此列表保存的是对象的指针, 比如[1,2,3,4] 需要四个指针与四个数值, 比较浪费内存和计算时间. ndarray是numpy的基本数据结构,  所有元素是同一种类型, 有丰富的函数, 计算效率也很高.

     

    1. 示例 

    import numpy as np
    a=np.array([1,2,3]) # 生成一个数组
    print(a)
    b=np.array([[1,2],[3,4]])  # 二维数组, 也可以b=np.array([(1,2),(3,4)]) 
    print(b)
    print(np.arange(1,5,0.5)) #开始,结束,步长, 5取不到!
    #[ 1.   1.5  2.   2.5  3.   3.5  4.   4.5]
    # numpy 包里面也有random 函数
    print(np.random.random((2,2)))#2*2随机浮点数数组
    print(np.linspace(1,2,11,endpoint=False)) # 1-2之间插入数字, 共11个数
    print(np.linspace(1,2,11)) #默认2能够取到, 即endpoint=True
    # [1.  1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2. ]
    print(np.ones([2,3]))
    print(np.zeros([2,2]))
    # 这个功能超级强大
    print(np.fromfunction(lambda i,j:(i+1)*(j+1),[2,3])) # 2*3数组

    [1 2 3]

    [[1 2]

     [3 4]]

    [1.  1.5 2.  2.5 3.  3.5 4.  4.5]

    [[0.93912717 0.52333486]

     [0.21249562 0.04995071]]

    [1.         1.09090909 1.18181818 1.27272727 1.36363636 1.45454545

     1.54545455 1.63636364 1.72727273 1.81818182 1.90909091]

    [1.  1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2. ]

    [[1. 1. 1.]

     [1. 1. 1.]]

    [[0. 0.]

     [0. 0.]]

    [[1. 2. 3.]

     [2. 4. 6.]]

    数组的元素提取

    import numpy as np
    a=np.array([(1,2,3),(4,5,6)])
    print(a[1]) # [4 5 6]
    print(a[0:2])
    #[[1 2 3]
    # [4 5 6]]
    print(a[:,[0,1]]) 
    #[[1 2]
    # [4 5]]
    print(a[1,[0,1]]) # [4 5]
    for i in a:
        print(i)
    #[1 2 3]
    #[4 5 6]

    数组的shape改变

    import numpy as np
    a=np.array([(1,2,3),(4,5,6)])
    print(a.shape) # (2, 3)
    b=a.reshape(3,2)  # 没有改变a
    print(b)
    #[[1 2]
    # [3 4]
    # [5 6]]
    a.resize(3,2)  # 改变了a

    数组之间的拼接

    import numpy as np
    a=np.array([1,2,3])
    b=np.array([[1,2],[3,4]])
    c=np.array([4,5,6])
    print(np.hstack((a,c))) #横向连接 [1 2 3 4 5 6]
    print(np.vstack((a,c)))#纵向连接 得到2*3数组
    print(b.T) #转置
    print(a+c)#对应元素相加 [5 7 9]

    结果: 

    [1 2 3 4 5 6];
    [[1 2 3]
     [4 5 6]] ;
    [[1 3]
     [2 4]] ;

    [5 7 9];

    不同形式的数组可以相加 相乘(对应元素之间)

    import numpy as np
    a=np.array([1,2,3])  # 行向量
    b=np.array([[1,3,5],[3,6,1]])
    print(a+b)
    #[[2 5 8]
    #[4 8 4]]
    
    a=np.array([[1],[3]]) # 列向量 , 形状不同也可以相加, 但是一个维度要相等
    b=np.array([[1,3,5],[3,6,1]])
    print(a+b)
    #[[2 4 6]
     #[6 9 4]]
    
    # 但这里不可以是a=np.array([1,2]), a必须与b 的其中一个维度相等!!

    通过list生成数组

    import numpy as np
    a=np.array([1,2,3])
    x=[1,2,3]
    xx=np.array(x)
    print(xx) #  [1 2 3]
    y=[[1,2],[3,4]]
    yy=np.array(y)  # 二维数组
    print(yy) 
    print(yy.flatten()) #展平,这不能作用于列表,只能作用于数组 [1 2 3 4]

    对数组的简单运算

    import numpy as np
    b=np.array([[1,2],[3,4]])
    print(b.sum()) #10
    print(b.sum(axis=0))#按列求和 [4 6] 
    print(b.sum(axis=1))#按行求和  [3 7]
    print(b.min()) # 1
    print(b.argmax())#max的下标 3  , 实际顺序按照列来排
    print(b.mean())  # 2.5
    print(b.std()) # 1.118

    总结

    注意:数组的属性函数不需要末尾加()  !! 

    b=np.array([[1,2],[3,4]])
    print(b.size)#元素个数 4
    print(b.ndim)#秩 2
    print(b.shape)  # (2L, 2L)
    print(b.dtype)#元素类型 int32

    示例:  numpy比math的计算速度更快

    import numpy as np
    import time
    import math
    x=np.arange(0,100,0.01)
    t1=time.clock()
    for i,t in enumerate(x):
        x[i]=math.pow((math.sin(t)),2)
    t2=time.clock()
    
    y=np.arange(0,100,0.01)
    t3=time.clock()
    y=np.power(np.sin(y),2)
    t4=time.clock()
    print('running time of math is:',t2-t1)
    print('running time of numpy is:',t4-t3)
    
    ans:
    ('running time of math is:', 0.011655904997766612)
    ('running time of numpy is:', 0.0023625201675097404)

    numpy与scipy的结合使用

    (1)实现矩阵的一些运算

    实例

    import numpy as np
    from scipy import linalg
    a=np.array([[1,0],[1,2]])
    print(np.dot(a,a)) # 矩阵乘法
    print(linalg.det(a)) # 行列式=2.0
    print(linalg.inv(a))
    x,y=linalg.eig(a)
    print(x) #特征值
    print(y)#特征向量??奇怪的值,随便给出的一个特征向量

    结果: 

    [[1 0]
     [3 4]]
    2.0
    [[ 1.  -0. ]
     [-0.5  0.5]]
    [ 2.+0.j  1.+0.j]
    [[ 0.          0.70710678]
     [ 1.         -0.70710678]]

    实际上 , 不用import linalg也可以, numpy下面也有一个linalg

    import numpy as np
    x=np.array([[1,2],[3,4]])
    r1=np.linalg.det(x)
    print(r1)
    r2=np.linalg.inv(x)
    print(r2)

     (2)聚类分析

    import numpy as np
    from scipy.cluster.vq import vq,kmeans,whiten
    list1=[89,90,76,90]
    list2=[96,78,89,79]
    list3=[90,98,89,80]
    list4=[80,72,79,84]
    list5=[92,81,89,87]
    data=np.array([list1,list2,list3,list4,list5])
    print(data)
    whiten=whiten(data)
    centroids,_=kmeans(whiten,2)
    result,_=vq(whiten,centroids)
    print(result) 

    [[89 90 76 90]

     [96 78 89 79]
     [90 98 89 80]
     [80 72 79 84]
     [92 81 89 87]] ;
    [1 1 1 0 1]  ;

    三维数组

    import numpy as np
    b=np.arange(24).reshape(2,3,4)
    print(b)
    print(b[1])#访问第二层
    print(b[0,1,::2])#,[4 6]间隔是2
    print(b[0,1,[1,2]]) # [5 6]
    print(b[::-1]) #两层交换
    print(b.ravel())#展平变一维的数组
    print(b.reshape(6,4))

    结果: 

    [[[ 0  1  2  3]
      [ 4  5  6  7]
      [ 8  9 10 11]]
     [[12 13 14 15]
      [16 17 18 19]
      [20 21 22 23]]]
    [[12 13 14 15]
     [16 17 18 19]
     [20 21 22 23]]
    [4 6]
    [5 6]
    [[[12 13 14 15]
      [16 17 18 19]
      [20 21 22 23]]
     [[ 0  1  2  3]
      [ 4  5  6  7]
      [ 8  9 10 11]]]
    [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
    [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]
     [12 13 14 15]
     [16 17 18 19]
     [20 21 22 23]]

    三维数组的一些操作

    import numpy as np
    x=np.array([[1,2,3],[4,5,6],[7,8,9]])
    #分割数组
    x1,x2,x3=np.hsplit(x,3)
    print(x1) #得到[1,4,7] 列向量形式
    y1,y2,y3=np.vsplit(x,3)
    print(y1)#得到[1,2,3] 行向量
    z=np.array([1+2.j,3+4.j])
    print(z.real) # [ 1. 3.]
    print(z.tolist()) # [(1+2j), (3+4j)]
    print(x.tolist())

    [1]
     [4]
     [7]]
    [[1 2 3]]
    [ 1.  3.]
    [(1+2j), (3+4j)]
    [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

    numpy包中其他常用的函数

    import numpy as np
    x=np.eye(2)
    print(x)
    np.savetxt('eye.txt',x)  # 将结果保存到txt 
    x1=np.array([9,30,20,39,12])
    print(np.diff(x1)) # [ 21 -10  19 -27], 数组长度-1
    print(np.ptp(x1)) # 30 极差: 最大最小的之差
    print(np.median(x1)) # 20
    print(np.msort(x1)) # [ 9 12 20 30 39]

    [[ 1.  0.]

     [ 0.  1.]],  得到txt文件如下

     下标对应

    import numpy as np
    d=np.array([1,2,4,11,27,34,2,21])
    price=np.array([11,22,41,15,29,32,20,61])
    ind=np.where(d==2)
    print(list(ind))  #  [array([1, 6], dtype=int64)]
    print(np.take(price,ind))  # [[22 20]]

    数组修剪

    import numpy as np
    a=np.arange(6)
    print(a) # [0 1 2 3 4 5]
    a1=a.clip(2,3) # 比2 小的变2 ,变3 大的变3
    print(a1) # a 没有改变!  a1= [2 2 2 3 3 3]
    b=np.arange(6)
    print(b.compress(b>2))  #b没有改变!  [3 4 5]

    数组的连乘

    import numpy as np
    a=np.arange(1,5)
    print(a.prod()) # 24
    print(a.cumprod()) # [ 1  2  6 24]

    统计: 协方差cov , 相关系数corr

    import numpy as np
    a=np.array([1,4,9,-1,3,6])
    b=np.array([11,24,19,-12,30,48])
    cov=np.cov(a,b)  # 生成协方差矩阵
    print(cov)
    corr=np.corrcoef(a,b)
    print(corr)
    print(cov.diagonal()) #协方差矩阵的对角线 即为方差 [  12.66666667  401.2       ]
    print(corr.trace()) # 相关系数矩阵你的对角线元素之和, 全为1,和一定=2.0 

    得到两个矩阵为: 

    [[  12.66666667   45.6       ]

     [  45.6         401.2       ]]

    [[ 1.          0.63966591]

     [ 0.63966591  1.        ]]

    多项式拟合

    import numpy as np
    a=np.array([1,4,9,3,6,12,19])
    t=np.arange(len(a))
    print(t)  # [0 1 2 3 4 5 6]
    poly=np.polyfit(t,a,3)
    print(poly) #三次方差的系数,阶数由高到低: 
    # [ 0.36111111 -2.73809524 6.54365079 0.92857143]
    print(np.polyval(poly,0)) # 0.928571428571 print(np.polyval(poly,t[-1]+1)) # 预测下一个t 36.4285714286

    np 数组转为list, 并排序等

    import numpy as np
    a=np.array([1,4,9,3,6,12,19])
    print(a.tolist()) # 列表  [1, 4, 9, 3, 6, 12, 19]
    print(np.argsort(a)) # 返回排序后的下标 [0 3 1 4 2 5 6]
    b=np.array([[10,8,3],[4,6,8]])
    print(np.sort(b)) # 每行进行从小到大排布
    print(np.msort(b))   # 每列进行从小到大排布

    [[ 3  8 10]
     [ 4  6  8]] ;

    [[ 4  6  3]
     [10  8  8]] ;

    条件筛选

    import numpy as np
    a=np.array([1,4,9,3,6,3,12,19])
    print(np.where(a==3)) # (array([3, 5], dtype=int64),)
    print(np.extract(a>3,a)) # [ 4  9  6 12 19]  保留>3的数
    print(np.take(a,[2,4])) # 找出a的下标是[2,4]的元素 为[9 6]

     mod 余数问题

    import numpy as np
    print(np.mod(10,-3))# -2 与除数的符号一致
    print(np.mod(-10,3)) # 2
    print(np.fmod(10,-3)) # 1 与被除数的符号一致
    print(np.fmod(-10,-3)) # -1
    print(x1*x2)  # 两者等价
    print(np.multiply(x1,x2))

    条件

    import numpy as np
    x=np.arange(10)
    print(np.where(x<5,9-x,x)) # [9 8 7 6 5 5 6 7 8 9]
    print(np.select([x<2,x>6,True],[7-x,x,2*x])) #[ 7  6  4  6  8 10 12  7  8  9]
    
    print(np.piecewise(x, [x<2,x>6], [lambda x:7-x,lambda x:x,lambda x:2*x]))
    
    a=np.array([1,4,2])
    print(np.piecewise(a,[a==1],[100])) # [100   0   0]
    c=np.array([-2,4,10])
    print(np.piecewise(c, [c>0, c<0], [-1,1])) # [-1,1,1]

    Note: piecewise中funclist如果不是数值而是函数时要使用lambda表达式,不能使用简单表达式7-x,否则会出错

    np库中的random函数

    import numpy as np
    print(np.random.rand()) #
    print(np.random.rand(2,3))
    print(np.random.standard_normal(2))
    print(np.random.randint(2,6,(2,3))) # 2*3数组

    0.10520553884752792

    [[ 0.23205959  0.86906066  0.82928021]
     [ 0.9032334   0.88635683  0.32403535]]
    [-0.23941662  0.53619398]
    [[5 4 4]
     [2 3 3]]

     综合应用实例  

    已知一只股票每日的收盘价信息:price.txt文件,第一个为space

    下面对收盘价c 成交量v等信息作简单统计

    复制代码
    import numpy as np
    c,v=np.loadtxt(r'C:UsersxuyinDesktop	estprice.txt',
    delimiter=',',usecols=(5,6),unpack=True)#读取closedprice,与volume成交量
    t=np.arange(len(c))
    #计算VWAP(volume_weighted average price)
    vwap=np.average(c,weights=v)
    print vwap
    twap=np.average(c,weights=t)#(time_weighted average price)
    print twap
    print np.ptp(c)#极差
    print c.ptp()#与上述一样
    print np.median(c)
    print np.msort(c)#从小到大排列,
    print np.var(c)
    print c.var()#与上述一样
    复制代码

    ans:

    110.374338624
    111.763157895
    27.0
    27.0
    111.0
    [  98.   98.  100.  100.  103.  103.  103.  105.  108.  111.  111.  113.
      113.  113.  115.  117.  119.  121.  123.  125.]
    68.1475
    68.1475

    复制代码
    returns=np.diff(c)/c[:-1]#计算每日收益率(第一天没有)
    print returns
    good=np.where(returns>0)#获得index
    print good
    print len(good)#得到1,所以不能这么统计,
    print len(c[good])
    print float(len(c[good])/float(len(c)-1))
    print 'the number of profiting days is %.1f'%float(len(c[good])/float(len(c)-1))
    logreturns=np.diff(np.log(c))#对数收益率
    #如何快速将列表的数格式化?
    复制代码

    ans:

    [ 0.02857143  0.02777778 -0.07207207 -0.04854369  0.15306122 -0.11504425
      0.23       -0.09756098  0.01801802 -0.13274336  0.21428571 -0.01680672
     -0.11965812  0.          0.11650485 -0.13043478  0.13        0.07079646
      0.03305785]
    (array([ 0,  1,  4,  6,  8, 10, 14, 16, 17, 18], dtype=int64),)
    1
    10
    0.526315789474
    the number of profiting days is 0.5

    APPLE一周股价的整理,

    复制代码
    import numpy as np
    import datetime 
    def datestr2num(s):
        return datetime.datetime.strptime(s,'%Y-%m-%d').date().weekday()
    #strptime(s,'%Y-%m-%d')表示将s转化为%Y-%m-%d'形式,date().weekday()表示一种格式,
    #将周一_周日分别用0,1,2..6表示,注意y一定要大写Y!!!Y是四位数的年表示
    o,h,l,c=np.loadtxt(r'C:UsersxuyinDesktop	estprice.txt',
    delimiter=',',usecols=(range(3,7)),unpack=True)
    d=np.loadtxt(r'C:UsersxuyinDesktop	estprice.txt',
    delimiter=',',usecols=(1,),converters={1:datestr2num},unpack=True)
    #计算工作日的收盘均值,剔除周末(5,6)
    aveg=np.zeros(5)
    for i in range(5):
        ind=np.where(d==i)
        aveg[i]=round(np.mean(c[ind]),2)
    print aveg
    
    #一周数据汇总,(源数据有三周的数据),要得到这三周的周open.high,low,close
    #先找三周的数据剔除工作日的数据
    #找到第一个周一,0与第三个周五
    mon1=np.ravel(np.where(d==0))[0]#返回指标
    fri3=np.ravel(np.where(d==4))[-1]
    ind=np.arange(mon1,fri3+1)
    weekind=[]#list
    #剔除中间的2组5 6数据
    for i in range(len(ind)):
        if (i+1)%7!=6 and (i+1)%7!=0:
    #        print(i)
    #        print(ind[i])
            weekind.append(ind[i])
    weekind=np.array(weekind)
    weekind=np.split(weekind,3)#分成三组  
    print weekind
    def summarize(a,o,h,l,c):
        weekopen=o[a[0]]#a表示指标
        weekhigh=np.max(h[a])
        weeklow=np.min(l[a]) 
        weekclose=c[a[-1]]
        return('APPLE',weekopen,weekhigh,weeklow,weekclose)
      
    weeksummary=np.apply_along_axis(summarize,1,weekind,o,h,l,c)
    #np.apply_along_axis会调用另一个函数作用于数组的每一个元素上
    #numpy.apply_along_axis(func, axis, arr, *args, **kwargs):
    #axis表示作用的轴,1表示横轴,
    np.savetxt(r'C:UsersxuyinDesktopweeksum.txt',
    weeksummary,delimiter=',',fmt='%s')#存储格式是s
    weekp1=np.loadtxt(r'C:UsersxuyinDesktopweeksum.txt',
    delimiter=',',usecols=(1,),unpack=True)#表示续行
    print weekp1
    复制代码

    ans:

    [ 243.33  210.    224.    237.33  240.  ]
    [array([1, 2, 3, 4, 5], dtype=int64), array([ 8,  9, 10, 11, 12], dtype=int64), array([15, 16, 17, 18, 19], dtype=int64)]
    [ 125.  123.  130.]

    #np.apply_along_axis会调用另一个函数作用于数组的每一个元素上
    #numpy.apply_along_axis(func, axis, arr, *args, **kwargs):
    #axis表示作用的轴,1表示横轴,

    复制代码
    def my_func(a):
        return (a[0] + a[-1]) * 0.5
    b=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
    print np.apply_along_axis(my_func, 0, b)
    #输出: array([ 5., 6., 7., 8.])
    print np.apply_along_axis(my_func, 1, b)
    #输出: array([ 2.5, 6.5, 10.5])
    复制代码

    分析时间数据:???waiting ...太懒了还么, 未完待续

    numpy as np
    a=np.array([1,4,9,-1,3,6])
    b=np.array([11,24,19,-12,30,48])
    cov=np.cov(a,b) # 生成协方差矩阵
    print(cov)
    corr=np.corrcoef(a,b)
    print(corr)
    print(cov.diagonal()) #协方差矩阵的对角线 即为方差 [ 12.66666667 401.2 ]
    print(corr.trace()) # 相关系数矩阵你的对角线元素之和, 全为1,和一定=2.0

    import numpy as npa=np.array([1,2,3]) # 生成一个数组print(a)b=np.array([[1,2],[3,4]])  # 二维数组, 也可以b=np.array([(1,2),(3,4)]) print(b)print(np.arange(1,5,0.5)) #开始,结束,步长, 5取不到!#[ 1.   1.5  2.   2.5  3.   3.5  4.   4.5]# numpy 包里面也有random 函数print(np.random.random((2,2)))#2*2随机浮点数数组print(np.linspace(1,2,11,endpoint=False)) # 1-2之间插入数字, 共11个数print(np.linspace(1,2,11)) #默认2能够取到, 即endpoint=True# [1.  1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2. ]print(np.ones([2,3]))print(np.zeros([2,2]))# 这个功能超级强大print(np.fromfunction(lambda i,j:(i+1)*(j+1),[2,3])) # 2*3数组

    ----END---- HAVE A GOOD ONE! 以上为本人课余自学工具书/blog的笔记整理, 常有更新, 非100%原创!且读且学习。
  • 相关阅读:
    深入浅出Blazor webassembly之Local storage
    深入浅出Blazor webassembly之一种简单的部署方法
    深入浅出Blazor webassembly之以SubDirectory方式部署
    深入浅出Blazor webassembly之理解 Blazor WASM
    深入浅出Blazor webassembly之Logging
    [转]解决github不能访问的问题
    深入浅出Blazor webassembly之使用State container机制实现两组件联动
    深入浅出Blazor webassembly之使用EventCallback机制进行组件之间联动
    跳槽一年后的回顾
    Node.js躬行记(12)——BFF
  • 原文地址:https://www.cnblogs.com/xuying-fall/p/8193965.html
Copyright © 2011-2022 走看看