zoukankan      html  css  js  c++  java
  • Numpy学习

    前言

    最近在DL里被各种矩阵计算虐得很渣,决定学习一波numpy

    正文

    1、先学习一下用numpy打开txt文件

    import numpy
    
    world_alcohol = numpy.genfromtxt("world_alcohol.txt",delimiter=",",dtype=str)
    print(type(world_alcohol))
    print(world_alcohol)
    print(help(numpy.genfromtxt))

    #
    <class 'numpy.ndarray'>
    [['Year' 'WHO region' 'Country' 'Beverage Types' 'Display Value']
     ['1986' 'Western Pacific' 'Viet Nam' 'Wine' '0']
     ['1986' 'Americas' 'Uruguay' 'Other' '0.5']
     ...
     ['1987' 'Africa' 'Malawi' 'Other' '0.75']
     ['1989' 'Americas' 'Bahamas' 'Wine' '1.5']
     ['1985' 'Africa' 'Malawi' 'Spirits' '0.31']]

    txt内容如下:

    Year,WHO region,Country,Beverage Types,Display Value
    1986,Western Pacific,Viet Nam,Wine,0
    1986,Americas,Uruguay,Other,0.5
    1985,Africa,Cte d'Ivoire,Wine,1.62
    1986,Americas,Colombia,Beer,4.27
    1987,Americas,Saint Kitts and Nevis,Beer,1.98
    1987,Americas,Guatemala,Other,0
    1987,Africa,Mauritius,Wine,0.13
    1985,Africa,Angola,Spirits,0.39
    1986,Americas,Antigua and Barbuda,Spirits,1.55
    1984,Africa,Nigeria,Other,6.1
    1987,Africa,Botswana,Wine,0.2
    1989,Americas,Guatemala,Beer,0.62

    参数delimiter表示分割符号;dtype=str表示从文件中提取的数据以str格式存放;

    ndarray是numpy中的数据结构;

    2.ndarray

    vector = numpy.array([5,10,15,20])
    matrix = numpy.array([[5,10,15],[20,25,30],[35,40,45]])
    print(vector)
    print(matrix)

    #
    [ 5 10 15 20]
    [[ 5 10 15]
     [20 25 30]
     [35 40 45]]

     看一下维度

    vector1 = numpy.array([[1,2,3,4]])
    vector2 = numpy.array([1,2,3,4])
    print(vector1.shape)
    print(vector2.shape)
    matrix = numpy.array([[5,10,15],[20,25,30]])
    print(matrix.shape)

    #
    (1, 4)
    (4,)
    (2, 3)

    vector1可以看作是1×4的矩阵;vector2是一维数组,可以看作是列向量

    再看ndarray的运算

    a = np.array([[1,2,3],[4,5,6],[7,8,9]])
    b = np.array([1,2,3])
    c = np.array([[1,2,3]])
    print(np.dot(a,b))
    print('------------------')
    print(np.dot(b,a))
    print('------------------')
    print(np.dot(c,a))
    print('------------------')
    print(np.dot(b,b))
    print('------------------')
    print(a*a)

    #
    [14 32 50]
    ------------------
    [30 36 42]
    ------------------
    [[30 36 42]]
    ------------------
    14
    ------------------
    [[ 1  4  9]
     [16 25 36]
     [49 64 81]]

    a是3×3的矩阵,b是一个长度为3的一维数组,c是1×3的矩阵

    np.dot(a,b)可以看作是3×3的矩阵和3×1的矩阵相乘

    np.dot(b,a)看作是1×3的矩阵和3×3的矩阵相乘

    np.dot(c,a)看作是矩阵和矩阵相乘

    注意,np.dot(b,b)是向量内积,是把各个维度都加起来

    a*a是矩阵对应位置上各个元素的乘积

     ——————分割线——————————————

    numbers = numpy.array([1,2,3,'4'])
    print(numbers)
    numbers.dtype

    #

    ['1' '2' '3' '4']

    只要array中有一个元素不是int32或者int64,那么所有的元素数据类型就会变成其他的数据类型

    对txt文件进行操作

     1 Year,WHO region,Country,Beverage Types,Display Value
     2 1986,Western Pacific,Viet Nam,Wine,0
     3 1986,Americas,Uruguay,Other,0.5
     4 1985,Africa,Cte d'Ivoire,Wine,1.62
     5 1986,Americas,Colombia,Beer,4.27
     6 1987,Americas,Saint Kitts and Nevis,Beer,1.98
     7 1987,Americas,Guatemala,Other,0
     8 1987,Africa,Mauritius,Wine,0.13
     9 1985,Africa,Angola,Spirits,0.39
    10 1986,Americas,Antigua and Barbuda,Spirits,1.55
    11 1984,Africa,Nigeria,Other,6.1
    12 1987,Africa,Botswana,Wine,0.2
    13 1989,Americas,Guatemala,Beer,0.62

    ①去掉表头,取出第二行,第五列的值以及第三行,第三列的值

    world_alcohol = np.genfromtxt("world_alcohol.txt",delimiter=",",dtype=str,skip_header=1)
    uruguay_other_1986 = world_alcohol[1,4]
    third_country = world_alcohol[2,2]
    print(uruguay_other_1986)
    print(third_country)

    #
    0.5
    Cte d'Ivoire

     补充一下切片操作:

    vector = numpy.array([5,10,15,20])
    print(vector[0:3])

    #
    [ 5 10 15]

    取出第0-2个元素

     ——————分割线——————————————

    matrix = numpy.array([
                        [5,10,15],
                        [20,25,30],
                        [35,40,45]
                         ])
    print(matrix[:,1])

    #
    [10 25 40]

    取出第二列所有元素 

     ——————分割线——————————————

    matrix = numpy.array([
                        [5,10,15],
                        [20,25,30],
                        [35,40,45]
                         ])
    print(matrix[:,0:2])

    #
    [[ 5 10]
     [20 25]
     [35 40]]

    取出前两列元素

    判断

    vector = np.array([5.10,15,20])
    vector == 10

    #
    array([False, False, False])

    判断当前数据结构中有没有该元素

    也可以借bool值来进行索引

    vector = np.array([5,10,15,20])
    equal_to_ten = (vector == 10)
    print(equal_to_ten)
    print(vector[equal_to_ten])

    #
    [False  True False False]
    [10]

     当然,在矩阵中就是如下:

    matrix = np.array([
                        [5,10,15],
                        [20,25,30],
                        [35,40,45]
                         ])
    second_column_25 = (matrix[:,1]==25)
    print(second_column_25)
    print(matrix[second_column_25, :])

    #
    [False  True False]
    [[20 25 30]]

    对第二列的元素进行判断;然后取出元素等于25的那一列所在行

    ——————————-分割线——————————————

    接下去是数值类型转换

    vector = numpy.array(["1","2","3"])
    print(vector.dtype)
    print(vector)
    vector = vector.astype(float)
    print(vector.dtype)
    print(vector)

    #
    <U1
    ['1' '2' '3']
    float64
    [1. 2. 3.]

    从str类型转到float类型

    关于sum求和操作

    matrix = np.array([
                        [5,10,15],
                        [20,25,30],
                        [35,40,45]
                         ])
    print(matrix.sum(axis=1))
    print(matrix.sum(axis=0))
    [ 30  75 120]
    [60 75 90]

    axis=1表示按行求和;axis=0表示按列求和

     Numpy常用函数

    ①矩阵的属性

    print(np.arange(15))
    a = np.arange(15).reshape(3,5)
    print(a)
    print(a.shape)
    print(a.ndim)
    print(a.dtype.name)
    print(a.size)

    #

    [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]
    [[ 0  1  2  3  4]
     [ 5  6  7  8  9]
     [10 11 12 13 14]]
    (3, 5)
    2
    int32
    15

    np.arange,依次生成0-14的一维数组;

    reshape(3,5),转换为3×5的矩阵;

    ndim看看维度是多少

    dtype.name,看看元素数据类型

    size看看一共有多少元素 

    ②矩阵的初始化

    a = np.zeros((3,4))
    a

    #
    array([[0., 0., 0., 0.],
           [0., 0., 0., 0.],
           [0., 0., 0., 0.]])
     

    表示生成3行,四列的全0矩阵,其中(3,4)可以是[3,4]格式;

    默认dtype=np.float64

    ——————————————————分割线——————————

    np.ones((2,3,4), dtype=np.int32)

    #
    array([[[1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]],
    
           [[1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]]])

    表示生成2个3×4的全1矩阵

    ——————————————————分割线——————————

    np.arange(10,30,5)
    np.arange(0, 2, 0.3)
    np.arange(12).reshape(4,3)
    
    #
    [10 15 20 25]
    [0.  0.3 0.6 0.9 1.2 1.5 1.8]
    [[ 0  1  2]
     [ 3  4  5]
     [ 6  7  8]
     [ 9 10 11]]

    从10开始,每隔5取一个数,左闭右开

    ——————————————————分割线——————————

    np.random.random((2,3))
    
    #
    array([[0.04286104, 0.02303494, 0.35769307],
           [0.34801234, 0.63580499, 0.99897693]])

    表示随机生成2×3的矩阵

    ——————————————————分割线——————————

    from numpy import pi
    np.linspace(0, 2*pi, 100)
    
    #
    array([0.        , 0.06346652, 0.12693304, 0.19039955, 0.25386607,
           0.31733259, 0.38079911, 0.44426563, 0.50773215, 0.57119866,
           0.63466518, 0.6981317 , 0.76159822, 0.82506474, 0.88853126,
           0.95199777, 1.01546429, 1.07893081, 1.14239733, 1.20586385,
           1.26933037, 1.33279688, 1.3962634 , 1.45972992, 1.52319644,
           1.58666296, 1.65012947, 1.71359599, 1.77706251, 1.84052903,
           1.90399555, 1.96746207, 2.03092858, 2.0943951 , 2.15786162,
           2.22132814, 2.28479466, 2.34826118, 2.41172769, 2.47519421,
           2.53866073, 2.60212725, 2.66559377, 2.72906028, 2.7925268 ,
           2.85599332, 2.91945984, 2.98292636, 3.04639288, 3.10985939,
           3.17332591, 3.23679243, 3.30025895, 3.36372547, 3.42719199,
           3.4906585 , 3.55412502, 3.61759154, 3.68105806, 3.74452458,
           3.8079911 , 3.87145761, 3.93492413, 3.99839065, 4.06185717,
           4.12532369, 4.1887902 , 4.25225672, 4.31572324, 4.37918976,
           4.44265628, 4.5061228 , 4.56958931, 4.63305583, 4.69652235,
           4.75998887, 4.82345539, 4.88692191, 4.95038842, 5.01385494,
           5.07732146, 5.14078798, 5.2042545 , 5.26772102, 5.33118753,
           5.39465405, 5.45812057, 5.52158709, 5.58505361, 5.64852012,
           5.71198664, 5.77545316, 5.83891968, 5.9023862 , 5.96585272,
           6.02931923, 6.09278575, 6.15625227, 6.21971879, 6.28318531])

    表示从0开始,到2π,按均匀分布取100个值

    ——————————————分割线—————————

    a = np.array([20,30,40,50])
    b = np.arange(4)
    print(a)
    print(b)
    c = a-b
    print(c)
    c = c-1
    print(c)
    print(b**2)
    print(a<35)
    
    #
    [20 30 40 50]
    [0 1 2 3]
    [20 29 38 47]
    [19 28 37 46]
    [0 1 4 9]
    [ True  True False False]

    a-b就是每个对应位置元素相减

    ———————————————分割线———————

    A = np.array([[1,1],
                 [0,1]])
    B = np.array([[2,0],
                 [3,4]])
    print(A)
    print('------------')
    print(B)
    print('------------')
    print(A*B)
    print('------------')
    print(A.dot(B))
    print('------------')
    print(np.dot(A, B))
    
    #
    [[1 1]
     [0 1]]
    ------------
    [[2 0]
     [3 4]]
    ------------
    [[2 0]
     [0 4]]
    ------------
    [[5 4]
     [3 4]]
    ------------
    [[5 4]
     [3 4]]

    前文也详细写了numpy不同乘法的区别

    ③矩阵常用操作

    B = np.arange(3)
    print(B)
    print(np.exp(B))
    print(np.sqrt(B))
    
    #
    [0 1 2]
    [1.         2.71828183 7.3890561 ]
    [0.         1.         1.41421356]
    
    

    exp表示e的x次幂;sqrt表示开平方

    ———————————————分割线———————

    a = np.floor(10*np.random.random((3,4)))
    print(a)
    print('--------------')
    print(a.ravel())
    print('--------------')
    a.shape = (6,2)
    print(a)
    print('--------------')
    print(a.T)

    #
    [[8. 3. 6. 2.]
     [0. 8. 7. 3.]
     [5. 2. 0. 7.]]
    --------------
    [8. 3. 6. 2. 0. 8. 7. 3. 5. 2. 0. 7.]
    --------------
    [[8. 3.]
     [6. 2.]
     [0. 8.]
     [7. 3.]
     [5. 2.]
     [0. 7.]]
    --------------
    [[8. 6. 0. 7. 5. 0.]
     [3. 2. 8. 3. 2. 7.]]

    floor表示向下取整,也就是往小的数取整;

    a.ravel()表示把矩阵拉成一个向量;

    a.shape=(6,2) 相当于a = a.reshape(6,2)

    也可以是a.shape=(6,-1)或者a = a.reshape(6,-1)意思是指定一个维度,另一个维度自己去算

    a.T也就是求转置

    —————————————分割线————————

    a = np.floor(10*np.random.random((2,2)))
    b = np.floor(10*np.random.random((2,2)))
    print(a)
    print('-----')
    print(b)
    print('-----')
    print(np.hstack((a,b)))
    print('-----')
    print(np.vstack((a,b)))

    #
    [[6. 7.]
     [1. 1.]]
    -----
    [[0. 3.]
     [9. 9.]]
    -----
    [[6. 7. 0. 3.]
     [1. 1. 9. 9.]]
    -----
    [[6. 7.]
     [1. 1.]
     [0. 3.]
     [9. 9.]]

    hstack表示按行拼接;vstack表示按列拼接

    ————————————————分割线——————

    a = np.floor(10*np.random.random((2,12)))
    print(a)
    print('------')
    print(np.hsplit(a,3))
    print('------')
    print(np.hsplit(a,(3,4)))
    a = np.floor(10*np.random.random((12,2)))
    print('------')
    print(a)
    np.vsplit(a,3)

    #
    [[4. 6. 5. 6. 0. 9. 7. 9. 3. 3. 0. 6.]
     [5. 5. 6. 1. 6. 2. 5. 3. 3. 9. 8. 1.]]
    ------
    [array([[4., 6., 5., 6.],
           [5., 5., 6., 1.]]), array([[0., 9., 7., 9.],
           [6., 2., 5., 3.]]), array([[3., 3., 0., 6.],
           [3., 9., 8., 1.]])]
    ------
    [array([[4., 6., 5.],
           [5., 5., 6.]]), array([[6.],
           [1.]]), array([[0., 9., 7., 9., 3., 3., 0., 6.],
           [6., 2., 5., 3., 3., 9., 8., 1.]])]
    ------
    [[2. 0.]
     [0. 2.]
     [1. 4.]
     [3. 7.]
     [0. 0.]
     [7. 5.]
     [0. 7.]
     [3. 5.]
     [7. 9.]
     [1. 4.]
     [2. 4.]
     [8. 1.]]
    [array([[2., 0.],
           [0., 2.],
           [1., 4.],
           [3., 7.]]), array([[0., 0.],
           [7., 5.],
           [0., 7.],
           [3., 5.]]), array([[7., 9.],
           [1., 4.],
           [2., 4.],
           [8., 1.]])]
    hsplit(a,3)表示按行切分,均分成3部分;

    hsplit(a,(3,4))表示在第2个位置切分,以及第3个位置切分
    同理,vsplit表示按列切分
    ③复制常用操作
    a = np.arange(12)
    b = a
    print(b is a)
    b.shape = 3,4
    print(a.shape)
    print(id(a))
    print(id(b))

    #
    True
    (3, 4)
    2570788546080
    2570788546080
    赋值操作,a和b完全指向一个元素,把b的维度修改一下,a也改变了
    ————————————————分割线——————————————————
    c = a.view()
    print(c is a)
    c.shape =2,6
    print(a.shape)
    c[0,4] = 1234
    print(a)
    print(id(a))
    print(id(c))

    #
    False
    (3, 4)
    [[   0    1    2    3]
     [1234    5    6    7]
     [   8    9   10   11]]
    2570788546080
    2570788626560

    可以看出这是一个浅复制,a和c指向不同的元素,但共用值,改变c的元素,其实也改变了a的元素

    ————————————————分割线——————————————————
     那么既想让复制的值指向不同的元素,也不想让他们共用值,可以进行深复制
    d = a.copy()
    d is a
    d[0,0]= 9999
    print(d)
    print(a)
    
    #
    
    [[9999    1    2    3]
     [   4    5    6    7]
     [   8    9   10   11]]
    [[ 0  1  2  3]
     [ 4  5  6  7]
     [ 8  9 10 11]]
    
    

    改变d的元素,对a毫无影响,同时改变a或者d的维度,对对方也毫无影响

    ————————————————分割线————————————————
    补充一点关于索引的内容
    data = np.sin(np.arange(20)).reshape(5,4)
    print(data)
    ind = data.argmax(axis=0)
    print(ind)
    data_max = data[ind, range(data.shape[1])]
    print(data_max)

    #
    [[ 0.          0.84147098  0.90929743  0.14112001]
     [-0.7568025  -0.95892427 -0.2794155   0.6569866 ]
     [ 0.98935825  0.41211849 -0.54402111 -0.99999021]
     [-0.53657292  0.42016704  0.99060736  0.65028784]
     [-0.28790332 -0.96139749 -0.75098725  0.14987721]]
    [2 0 3 1]
    [0.98935825 0.84147098 0.99060736 0.6569866 ]
    axis表示按列索引;
    ind相当于是把每列中最大数的行给拿出来放到一个ndarray中;
    注意data[,]取数的方法,很巧妙,ind是按行作索引,range(data.shape[1])相当于把一共多少列给变成了range循环(python基础)

    ————————————分割线—————————

    接下去是扩展操作

    a = np.arange(0,40,10)
    print(a)
    b= np.tile(a,(3,5))
    print(b)
    
    #
    [ 0 10 20 30]
    [[ 0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30]
     [ 0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30]
     [ 0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30]]

    相当于把一个维度的向量扩展成所需类型的矩阵,矩阵每个元素都是相同的向量

    ————————————分割————————————

    a = np.array([[4,3,5],[1,2,1]])
    print(a)
    print('-------')
    b = np.sort(a,axis=1)
    print(b)
    a.sort(axis=1)
    print('-------')
    print(a)
    a = np.array([4,3,1,2])
    j= np.argsort(a)
    print('-------')
    print(j)
    print('-------')
    print(a[j])

    #
    [[4 3 5]
     [1 2 1]]
    -------
    [[3 4 5]
     [1 1 2]]
    -------
    [[3 4 5]
     [1 1 2]]
    -------
    [2 3 1 0]
    -------
    [1 2 3 4]

    axis=1表示按行索引排序

    argsort表示按元素值从小到大,对其索引进行排序

    a[j]又表示按照索引对其元素值进行排序,其实就是从小到大排序

    ————————————————分割线————————————
    x_data = np.linspace(-1,1,300)[:, np.newaxis]
    比如,今天写了这么一行代码,意思是生成-1到1的300个均匀分布值(300,),然后变成(300,1)
    noise = np.random.normal(0,0.05,x_data.shape)

    表示生成一个正态分布,均值为0,标准差为0.05,维度为x_data的维度,

    所以标准正态分布则是

    np.random.normal(loc=0,scale=1,size=None)

    也相当于

    np.random.randn(size=None)

    ————————————————分割线————————————

    又发现一个很绝的操作,那就是shuffle,先看代码
    
    
    p = np.random.permutation(3)
    a = np.array([1,0,2])
    print(a,p)
    print(type(a))
    print(type(p))
    print(np.array([1,2,3])[a])
    print(np.array([1,2,3])[p])

    #
    [1 0 2] [2 0 1]
    <class 'numpy.ndarray'>
    <class 'numpy.ndarray'>
    [2 1 3]
    [3 1 2]
    np.random.permutation(3)这个其实效果np.array是类似的,都是生成ndarray的一维数组,不同的是前一个函数是“字典”shuffle的,把数组已经打乱了,其实真正神奇的,原来
    ndarray格式的数据后面加[ndarray]这个索引,就可以对数组里面的元素起到按索引排序的效果,简直牛逼。。以前一直不知道!


    人生苦短,何不用python
  • 相关阅读:
    虚函数&纯虚函数&抽象类&虚继承
    指针的各式定义
    开源站点
    WCF、Net remoting、Web service概念及区别
    asp.net 分布式应用开发
    C++多重继承二义性解决
    ATL7窗口类详细剖析
    Code review
    GitHub 上100个最受欢迎的Java基础类库
    JAVA基本类库介绍
  • 原文地址:https://www.cnblogs.com/yqpy/p/11004190.html
Copyright © 2011-2022 走看看