Numpy基础入门学习,附代码

1. Ndarray 对象

函数定义:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称描述
object数组或嵌套的数列
dtype数组元素的数据类型
copy对象是否需要复制
order创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok默认返回一个与基类类型一致的数组
ndmin指定生成数组的最小维度

常用的参数有object,dtype以及ndmin,举例如下:

	import numpy as np
	
    a = np.array([1, 2, 3, 4, 5])
    b = np.array([1, 2, 3, 4, 5], dtype = complex, ndmin = 2)
    print("a最低(默认)一维,默认类型为整数:  ",a)
    print("b最低二维,数据类型为复数:  ",b)
    # 结果为:
    #   a最低(默认)一维,默认类型为整数:   [1 2 3 4 5]
    #   b最低二维,数据类型为复数:  [[1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j]]

2. dtype对象

函数定义:
numpy.dtype(object, align, copy)
常用的参数为object,即你需要转化为什么数据类型。numpy的数据类型同c/c++/java一样,属于强数据类型,包括np.int8,np.int16,np.float16,np.float32等,int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替。
dtype也可以定义结构化数据类型,如下:
 import numpy as np
    student = np.dtype([('name', 'S20'), ('age', 'i1'), ('marks', 'f4')])
    a = np.array([('abc', 21, 50), ('xyz', 18, 75)], dtype=student)
    print(a)
    print("名字:" ,a["name"])
    print(type(a[0]["age"]))
    # 结果为:
    #    [(b'abc', 21, 50.)(b'xyz', 18, 75.)]
    #    名字: [b'abc' b'xyz']
    #    <class 'numpy.int8'>

3. 数组属性

常用属性有:

属性描述
ndarray.ndim秩,即矩阵的维度
ndarray.shape矩阵的形状
ndarray.size矩阵元素总数
ndarray.dtype矩阵元素类型
ndarray.itemsize矩阵单个元素所占内存

范例:

	a = np.array([[1, 2, 3], [4, 5, 6]])
    print("矩阵的维度: " ,a.ndim)
    print("矩阵的形状: ", a.shape)
    print("矩阵元素总数: ",a.size )
    print("矩阵单个元素所占内存: ", a.itemsize)
    # 结果:
    #   矩阵的维度:  2
    #   矩阵的形状:  (2, 3)
    #   矩阵元素总数:  6
    #   矩阵单个元素所占内存:  4

4. 创建数组

4.1 随机值、定值创建
使用numpy.empty、numpy.zeros、numpy.ones分别创建元素值为:随机值、0值、1值的数组,方法参数有(shape, dtype , order),参数描述如下:

参数描述
shape数组形状
dtype元素类型
order排序方式,‘C’ 代表行优先, 'F’代表列优先

4.2 从已有数组中创建数组
4.2.1 numpy.asarray
使用numpy.asarray(object, dtype = None, order = None)方法从已有的元组、列表等变量中创建数组,参数说明如下:

参数描述
object已存在的元组、列表等
dtype元素类型
order排序方式,‘C’ 代表行优先, 'F’代表列优先

范例:

	x = [1, 2, 3]
    a = np.asarray(x, dtype=float)
    print("将列表转化为数组: " ,a)
    # 结果:
    #   将列表转化为数组:  [1. 2. 3.]

4.2.2 numpy.frombuffer
使用numpy.frombuffer 实现动态数组,以流的形式读入参数,转化成 ndarray 对象,函数定义为:
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
参数说明:

参数描述
buffer任意流对象
count从流中读取的数据量,值为“-1”时代表读取所有数据
offset读取数据的起始位置

范例:

    s1 = b'Hello World'
    # s1 = 'Hello World'   python 2.x 的写法
    a1 = np.frombuffer(s1, dtype='S1',count=4 , offset=3)
    print(a1)
    #结果:
    #  [b'l' b'o' b' ' b'W']

注:Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。
4.2.2 numpy.fromiter
该方法可以从一个迭代器中创建数组,函数定义为:
numpy.fromiter(iterable, dtype, count=-1)

参数描述
iterable迭代器对象
count从流中读取的数据量,值为“-1”时代表读取所有数据

范例:

	x = [1,2,3,4,5,6]
    # 生成迭代器
    a = iter(x)
    y = np.fromiter(a, dtype=float,count=4)
    print(y)
    #结果:
    #   [1. 2. 3. 4.]

4.3 从数值范围中创建数组
4.3.1 numpy.arange
最常用的就是numpy.arange(start, stop, step, dtype)方法,根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。

参数描述
start起始数值,默认为0
stop终止数值,不包含
step每次增加的步长,默认1

范例:

    x = np.arange(start=10,stop = 33, step =3, dtype = float)
    print(x)
    # 结果:
    #    [10. 13. 16. 19. 22. 25. 28. 31.]

注:生成的范围是左闭右开,不包含终止数值
4.3.2 numpy.linspace
此方法用于创建一个等差数列,函数定义:
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
常用参数说明:

参数描述
start起始数值
stop终止数值,不包含
num生成的数列元素个数,默认50
endpoint是否包含终止数值,true时包含
retstep为true时生成的数组中会显示间距

范例:

    a = np.linspace(start=0 ,stop=10,num=5 ,endpoint=True,retstep=True)
    print(a)
    # 结果:
    #    (array([ 0. ,  2.5,  5. ,  7.5, 10. ]), 2.5)

4.3.3 numpy.logspace
此方法用于生成一个等比数列,方法定义为:
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数说明:

参数描述
start起始数值为base**start
stop终止数值为base**stop,不包含
num生成的数列元素个数,默认50
endpoint是否包含终止数值,true时包含
baselog的底数

范例:

    a = np.logspace(start=1 ,stop=5,num=6 ,endpoint=True,base=2)
    print(a)
    # 结果:
    #    [ 2.  3.48220225  6.06286627 10.55606329 18.37917368 32.  ]

5. 切片

切片对象可以通过内置的 slice 函数,函数定义为:
slice(start, stop, step),参数分别为起始位置,终止位置,步长。除此之外,也可以通过“:”来简写切片,规则为:[start:stop:step].
范例:

    a = np.arange(10)
    s = slice(2,-4,1 )  # 从索引 2 开始到 倒数第4个位置停止,间隔为1
    print(a[s])
    print(a[2:7:1])
    # 结果:
    #   [2 3 4 5]
    #   [2 3 4 5 6]

注:
1.当位置为负数时,代表从尾部往前数,-2即倒数第二个位置。
2.在用“:”简写时,省略第一个数代表从第一个元素开始切片,省略第二个数代表切片至最后一个元素,省略最后一个数代表步长为1。切片范围为左闭右开,即不包含最右边的位置。

当切片用于多维数组时,效果大同小异,范例如下:

	a = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
    print("原数组:", a)
    print("第2列元素a[..., 1]:  ", a[..., 1])
    print("第2行元素a[1, ...]:  ", a[1, ...])
    print("第2行元素a[1]:  ", a[1])
    print("第2列及剩下的所有元素a[..., 1:]:  ", a[..., 1:])
    print("第2行及剩下的所有元素a[1:]:  ", a[1:])
    print("第1列和第3列元素:  ", a[..., 0:3:2])
    print("第1行和第3行元素:  ", a[0:3:2])
    print("第1行和第3行元素:  ", a[0:3:2,0:3])
    # 结果:
    # 原数组: [[0 1 2]
    #          [3 4 5]
    #          [6 7 8]]
    # 第2列元素a[..., 1]:    [1 4 7]
    # 第2行元素a[1, ...]:    [3 4 5]
    # 第2行元素a[1]:   [3 4 5]
    # 第2列及剩下的所有元素a[..., 1:]: [[1 2]
    #                                  [4 5]
    #                                  [7 8]]
    # 第2行及剩下的所有元素a[1:]:  [[3 4 5]
    #                             [6 7 8]]
    # 第1列和第3列元素:  [[0 2]
    #                   [3 5]
    #                   [6 8]]
    # 第1行和第3行元素: [[0 1 2]
    #                   [6 7 8]]
    # 第1行和第3行元素: [[0 1 2]
    #                   [6 7 8]]

其中,“…”代表选择元组的长度与数组的维度相同。可以看出,用于多位数列时,位置数字代表相对于的行数或者列数。

6. 索引

4.1 整数数组索引
直接看范例:

	x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
    print("原数组:  ",x)
    print("取位置为(1,1)(0,2)(3,0)的元素:\n")
    y = x[[1, 0, 3], [1, 2, 0]]
    print(y)

    rows = np.array([[0, 0], [3, 3]])
    cols = np.array([[0, 2], [0, 2]])
    y = x[rows, cols]
    print('这个数组的四个角元素是(结果为二维):')
    print(y)

    rows = np.array([0, 0, 3, 3])
    cols = np.array([0, 2, 0, 2])
    y = x[rows, cols]
    print('这个数组的四个角元素是(结果为一维):')
    print(y)

    # 使用...和:也能完成上述操作,如下
    print("...+:完成: " ,x[0:4:3,0:3:2])
    # 结果为:
    # 原数组:         [[ 0  1  2]
    #                  [ 3  4  5]
    #                  [ 6  7  8]
    #                  [ 9 10 11]]
    # 取位置为(1,1)(0,2)(3,0)的元素:   [4 2 9]
    # 这个数组的四个角元素是(结果为二维):
    #                                       [[ 0  2]
    #                                        [ 9 11]]
    # 这个数组的四个角元素是(结果为一维):     [ 0  2  9 11]
    # ...+:完成:      [[ 0  2]
    #                  [ 9 11]]

x[[1, 0, 3], [1, 2, 0]]写法中,列表前面的元素是行标,后面的元素是列标。
在取四个角坐标时,两种写法类似,行列坐标对应,不过取出的结果的维度不一样,一个为一维,一个为二维。
在用“…”+“:”组合取值时,则是用切片的知识,取第0行、第3行(步长是3)与第0列、第2列(步长是2)的交汇点的值。
4.2 布尔索引
即在取值时加入判断条件,如a[a>5]取a中值大于5的数,a[np.iscomplex(a)]取a中的复数,a[~np.isnan(a)]取a中非NA的数,范例:

	a = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
    print(a[~np.isnan(a)])
    a = a[~np.isnan(a)]
    print(a[a>3])
    # 结果:
    #    [1. 2. 3. 4. 5.]
    #    [4. 5.]
#结果

4.3 花式索引
直接看范例:

x=np.arange(20).reshape(5,4)
    print("原数组: \n",x)
    print("取第三、一、五、倒数第二行:\n",x[[2,0,4,-2]])

    print("按照0、3、1、2的列序取第0、3、1行的数\n",x[np.ix_([0, 3, 1], [0, 3, 1, 2])])
    # 结果:
    # 原数组:
    #       [[ 0  1  2  3]
    #       [ 4  5  6  7]
    #       [ 8  9 10 11]
    #       [12 13 14 15]
    #       [16 17 18 19]]
    # 取第三、一、五、倒数第二行:
    #       [[ 8  9 10 11]
    #       [ 0  1  2  3]
    #       [16 17 18 19]
    #       [12 13 14 15]]
    # 按照0、3、1、2的列序取第0、3、1行的数
    #       [[ 0  3  1  2]
    #       [12 15 13 14]
    #       [ 4  7  5  6]]

可以看出,和前面的切片类似,数字代表行数,负数代表从后往前的位置。
np.ix_([1,5,7,2],[0,3,1,2])函数有两个参数,前面代表行坐标,后面代表列坐标,与前面不同的是,这里一个行坐标会和每一个列坐标都交汇一次,即行坐标“1”会和“[0,3,1,2]”产生四个位置,即(1,0)、(1,3)、(1,1)、(1,2)。

注意注意!!!:
花式索引和布尔索引取得的效果和切片看似类似,但不完全一样,切片相当于“浅拷贝”,相当于取出的值还是在原来的内存,只是简单复制了数值,并未为这个值开辟一个新的内存空间,如果此时修改取出来的这个值,那么原变量的值也会相应改变。而花式索引和布尔索引是“深拷贝”,取出来的值会重新得到一个内存空间,这样修改取出来的值不会影响原来的变量。如果不清楚看下面的例子:

	x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
    print("原数组:  \n" ,x)
    y = x[1:3, 1:3]
    print("切片后: \n ",y)
    # 更改切片后的变量y(此时并未直接改变原变量x)
    y[1][1] = 100
    print("切片后的变量y:\n",y)
    print("原变量x:\n ",x)
    # 结果:
    #     原数组:
    #       [[0  1  2]
    #       [3  4  5]
    #       [6 7 8]
    #       [9 10 11]]
    #     切片后:
    #       [[4 5]
    #       [7 8]]
    #     切片后的变量y:
    #       [[4   5]
    #       [7 100]]
    #     原变量x:
    #       [[0   1   2]
    #       [3   4   5]
    #       [6 7 100]
    #       [9  10  11]]

可以看出,在修改切片后的数组y的数值后,原数组x的值也跟着改变了,而对于布尔和花式索引来说,则不会,如下:

    x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
    print("原数组:  \n" ,x)
    y = x[x > 5]
    print("切片后: \n ",y)
    # 更改切片后的变量y(此时并未直接改变原变量x)
    y[2] = 100
    print("切片后的变量y:\n",y)
    print("原变量x:\n ",x)
    # 结果:
    #     原数组:  
    #       [[ 0  1  2]
    #       [ 3  4  5]
    #       [ 6  7  8]
    #       [ 9 10 11]]
    # 切片后: 
    #       [ 6  7  8  9 10 11]
    # 切片后的变量y:
    #       [  6   7 100   9  10  11]
    # 原变量x:
    #       [[ 0  1  2]
    #       [ 3  4  5]
    #       [ 6  7  8]
    #       [ 9 10 11]]

看到更改y数组后,原x数组并未改变。

7. NumPy 广播

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式,当两个数组形状相同时,则两数组相乘时,直接是对应元素相乘,如两数组形状不同,则触发广播机制。例如:

	a = np.array([[0, 0, 0],
                  [10, 10, 10],
                  [20, 20, 20],
                  [30, 30, 30]])
    b = np.array([1, 2, 3])
    print(a + b)
    # 结果:
    #   [[1  2  3]
    #    [11 12 13]
    #    [21 22 23]
    #    [31 32 33]]

广播的规则:

1.让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
2.输出数组的形状是输入数组形状的各个维度上的最大值。
3.如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
4.当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。

简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:

1.数组拥有相同形状。
2.当前维度的值相等。
3.当前维度的值有一个是 1。

8.NumPy 迭代数组

数组中有很多元素,我们可以通过生成一个迭代器,通过逐步迭代来遍历数组元素,范例:

    a = np.arange(6).reshape(2, 3)
    print('原始数组是:\n' ,a)
    print('迭代输出元素:')
    for x in np.nditer(a):
        print(x, end=", ")
    # 结果:
    #     原始数组是:
    #       [[0 1 2]
    #        [3 4 5]]
    #     迭代输出元素:
    #       0, 1, 2, 3, 4, 5, 

在遍历矩阵的转置时,通常使用a.T来获得矩阵a的装置矩阵,但此时转置矩阵的内存地址还是原来的内存,所以遍历时的结果会和原矩阵一样,且修改转置矩阵时原矩阵也会改变,如下:

    a = np.arange(6).reshape(2, 3)
    print("原矩阵: \n",a)
    y = a.T
    print("转置矩阵: \n" ,y)
    y[1][1] = 100
    print("改变转置矩阵: \n" ,y)
    print("原矩阵: \n" ,a )
    print("按行优先遍历原矩阵")
    for x in np.nditer(a):
        print(x, end=", ")
    print("\n")
    print("按行优先遍历转置矩阵:")
    for x in np.nditer(y):
        print(x, end=", ")
    # 结果:
    #   原矩阵:
    #       [[0 1 2]
    #       [3 4 5]]
    #   转置矩阵:
    #       [[0 3]
    #       [1 4]
    #       [2 5]]
    #   改变转置矩阵:
    #       [[0   3]
    #       [1 100]
    #       [2 5]]
    #   原矩阵:
    #       [[0   1   2]
    #       [3 100   5]]
    #   按行优先遍历原矩阵
    #       0, 1, 2, 3, 100, 5,
    #   按行优先遍历转置矩阵:
    #       0, 1, 2, 3, 100, 5,

可以看出,改变转置矩阵y后,原矩阵也改变,且转置矩阵和原矩阵遍历结果一样。
而是用a.T.copy(order=‘C’)得到的转置矩阵会获得新的地址空间,order参数表示何种复制方式,“C”代表行优先,“F”代表列优先

    a = np.arange(6).reshape(2, 3)
    print("原矩阵: \n",a)
    y = a.T.copy(order='C')
    print("转置矩阵: \n" ,y)
    y[1][1] = 100
    print("改变转置矩阵: \n" ,y)
    print("原矩阵: \n" ,a )
    print("按行优先遍历原矩阵")
    for x in np.nditer(a):
        print(x, end=", ")
    print("\n")
    print("按行优先遍历转置矩阵:")
    for x in np.nditer(y):
        print(x, end=", ")
    # 结果:
    #   原矩阵: 
    #       [[0 1 2]
    #       [3 4 5]]
    #   转置矩阵: 
    #       [[0 3]
    #       [1 4]
    #       [2 5]]
    #   改变转置矩阵: 
    #       [[  0   3]
    #       [  1 100]
    #       [  2   5]]
    #   原矩阵: 
    #       [[0 1 2]
    #       [3 4 5]]
    #   按行优先遍历原矩阵
    #       0, 1, 2, 3, 4, 5, 
    #   按行优先遍历转置矩阵:
    #       0, 3, 1, 100, 2, 5,

nditer类的构造器拥有flags参数,它的传入参数有以下:

参数描述
c_index记录行优先遍历时的索引
f_index记录列优先遍历时的索引
multi_index每次迭代可以跟踪一种索引类型
external_loop给出的值是具有多个值的一维数组,而不是零维数组

范例:

    a = np.arange(0, 60, 5)
    a = a.reshape(3, 4)
    print('原始数组是:\n' , a)
    print('修改后的数组是:')
    for x in np.nditer(a, flags=['external_loop'], order='F'):
        print(x, end=", ")
    # 结果:
    #     原始数组是:
    #         [[0  5 10 15]
    #         [20 25 30 35]
    #         [40 45 50 55]]
    #     修改后的数组是:
    #         [0 20 40], [5 25 45], [10 30 50], [15 35 55],
    a=np.arange(6).reshape(2,3)
    print("记录列遍历索引:")
    p = np.nditer(a, flags=['f_index'])
    while not p.finished:
        print("<%s>" % (p.index) ,end=", ")
        p.iternext()
    print("\n记录行遍历索引:")
    p = np.nditer(a, flags=['f_index'])
    while not p.finished:
        print("<%s>" % (p.index) ,end=", ")
        p.iternext()
    # 结果:
    #     记录列遍历索引:
    #     < 0 >, < 2 >, < 4 >, < 1 >, < 3 >, < 5 >,
    #     记录行遍历索引:
    #     < 0 >, < 2 >, < 4 >, < 1 >, < 3 >, < 5 >,

9. 数组操作

9.1 常用属性
9.1.1 numpy.reshape
numpy.reshape函数用户改变矩阵的形状,函数定义为:
numpy.reshape(arr, newshape, order=‘C’)
其中arr传入原来的数组,newshape为新矩阵的形状,order为遍历顺序。范例:

    a = np.arange(8)
    print('原始数组:\n' ,a)
    b = a.reshape(4, 2)
    print('修改后的数组:\n' ,b)
    # 结果:
    #   原始数组:
    #       [0 1 2 3 4 5 6 7]
    #   修改后的数组:
    #       [[0 1]
    #       [2 3]
    #       [4 5]
    #       [6 7]]

9.1.2 numpy.flat
该函数用于得到一个数组的迭代器,可用于遍历数组,范例:

    a = np.arange(8).reshape(2,4)
    print('原始数组:')
    for row in a:
        print(row)
    print('迭代后的数组:')
    for element in a.flat:
        print(element ,end=",")
    # 结果:
    #   原始数组:
    #       [0 1 2 3]
    #       [4 5 6 7]
    #   迭代后的数组:
    #       0,1,2,3,4,5,6,7,

9.1.3 numpy.flatten
次函数返回一个深拷贝的数组,独立内存空间,对拷贝数组所做的修改不会影响原始数组,范例:

    a = np.arange(8).reshape(2,4)
    print('原始数组:\n' , a)
    b = a.flatten()
    print('展开的数组:\n', b)
    # 改变拷贝数组
    b[3] = 100
    print('展开的数组:\n' ,b)
    print('原始数组:\n', a)
    # 结果:
    #   原始数组:
    #       [[0 1 2 3]
    #       [4 5 6 7]]
    #   展开的数组:
    #       [0 1 2 3 4 5 6 7]
    #   展开的数组:
    #       [  0   1   2 100   4   5   6   7]
    #   原始数组:
    #       [[0 1 2 3]
    #       [4 5 6 7]]

9.1.3 numpy.ravel
返回的是数组视图,类似于浅拷贝,只是复制了数据,但内存地址未改变,改变拷贝数组会影响原数组,范例:

    a = np.arange(8).reshape(2,4)
    print('原始数组:\n' , a)
    b = a.ravel()
    print('展开的数组:\n', b)
    # 改变拷贝数组
    b[3] = 100
    print('展开的数组:\n' ,b)
    print('原始数组:\n', a)
    # 结果:
    #   原始数组:
    #       [[0 1 2 3]
    #       [4 5 6 7]]
    #   展开的数组:
    #       [0 1 2 3 4 5 6 7]
    #   展开的数组:
    #       [  0   1   2 100   4   5   6   7]
    #   原始数组:
    #       [[  0   1   2 100]
    #       [  4   5   6   7]]

9.2 翻转数组
numpy.transpose用于获得数组的转置,效果和a.T相似(也为浅拷贝),范例:

    a = np.arange(6).reshape(2,3)
    print('原始数组:\n' , a)
    y = np.transpose(a)
    print('翻转数组:\n' , y)
    # 改变翻转数组
    y[1] = 100
    print('翻转数组:\n' , y)
    print('原始数组:\n' , a)
    # 结果:
    #   原始数组:
    #       [[0 1 2]
    #       [3 4 5]]
    #   翻转数组:
    #       [[0 3]
    #       [1 4]
    #       [2 5]]
    #   翻转数组:
    #       [[  0   3]
    #       [100 100]
    #       [  2   5]]
    #   原始数组:
    #       [[  0 100   2]
    #       [  3 100   5]]

9.3 修改数组维度
9.3.1 numpy.broadcast
numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。

x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])  
# 对 y 广播 x
b = np.broadcast(x,y)  
# 它拥有 iterator 属性,基于自身组件的迭代器元组
print ('对 y 广播 x:')
r,c = b.iters
# Python3.x 为 next(context) ,Python2.x 为context.next()
print (next(r), next(c))
print (next(r), next(c))
print ('\n')
# shape 属性返回广播对象的形状
print ('广播对象的形状:')
print (b.shape)
print ('\n')
# 手动使用 broadcast 将 x 与 y 相加
b = np.broadcast(x,y)
c = np.empty(b.shape)
print ('手动使用 broadcast 将 x 与 y 相加:')
print (c.shape)
print ('\n')
c.flat = [u + v for (u,v) in b]
print ('调用 flat 函数:')
print (c)
print ('\n')
# 获得了和 NumPy 内建的广播支持相同的结果
print ('x 与 y 的和:')
print (x + y)

上面代码的结果为:

对 y 广播 x:
	1 4
	1 5
广播对象的形状:
	(3, 3)
手动使用 broadcast 将 x 与 y 相加:
	(3, 3)
调用 flat 函数:
	[[5. 6. 7.]
	 [6. 7. 8.]
 	 [7. 8. 9.]]
x 与 y 的和:
	[[5 6 7]
 	[6 7 8]
 	[7 8 9]]

9.3.2 numpy.broadcast_to
numpy.broadcast_to 函数将数组广播到新形状。它在原始数组上返回只读视图

a = np.arange(4).reshape(1,4)
print ('原数组:')
print (a)
print ('\n')
print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))
#结果为:
#原数组:
#[[0 1 2 3]]
#调用 broadcast_to 函数之后:
#[[0 1 2 3]
# [0 1 2 3]
# [0 1 2 3]
# [0 1 2 3]]

9.3.3 numpy.expand_dims
numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:
numpy.expand_dims(arr, axis)
arr是输入数组,axis是新轴插入的位置

x = np.array(([1,2],[3,4]))
 
print ('数组 x:')
print (x)
print ('\n')
y = np.expand_dims(x, axis = 0)
#数组 x:
#[[1 2]
# [3 4]]
 
print ('数组 y:')
print (y)
print ('\n')
 #数组 y:
 #    [[[1 2]
#       [3 4]]]
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
print ('\n')
#数组 x 和 y 的形状:
#   (2, 2) (1, 2, 2)
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1)
 
print ('在位置 1 插入轴之后的数组 y:')
print (y)
print ('\n')
#在位置 1 插入轴之后的数组 y:
#[[[1 2]]
# [[3 4]]]
 
print ('x.ndim 和 y.ndim:')
print (x.ndim,y.ndim)
print ('\n')
# x.ndim 和 y.ndim:
 # 2 3
 
print ('x.shape 和 y.shape:')
print (x.shape, y.shape)
#x.shape 和 y.shape:
#(2, 2) (2, 1, 2)

9.3.4 numpy.squeeze
numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:
numpy.squeeze(arr, axis)
axis:整数或整数元组,用于选择形状中一维条目的子集

x = np.arange(9).reshape(1,3,3)
print ('数组 x:')
print (x)
print ('\n')
y = np.squeeze(x)
print ('数组 y:')
print (y)
print ('\n')
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
数组 x:
[[[0 1 2]
  [3 4 5]
  [6 7 8]]]
数组 y:
[[0 1 2]
 [3 4 5]
 [6 7 8]]
数组 x 和 y 的形状:
(1, 3, 3) (3, 3)

9.4 连接数组

函数描述
concatenate连接沿现有轴的数组序列
stack沿着新的轴加入一系列数组。
hstack水平堆叠序列中的数组(列方向)
vstack竖直堆叠序列中的数组(行方向)

9.4.1 numpy.concatenate
numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:
numpy.concatenate((a1, a2, …), axis)

a1, a2, …:相同类型的数组
axis:沿着它连接数组的轴,默认为 0
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('\n')
# 两个数组的维度相同
print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('\n')
print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
第一个数组:
[[1 2]
 [3 4]]
第二个数组:
[[5 6]
 [7 8]]
沿轴 0 连接两个数组:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
沿轴 1 连接两个数组:
[[1 2 5 6]
 [3 4 7 8]]

9.4.2 numpy.stack
numpy.stack 函数用于沿新轴连接数组序列,格式如下:
numpy.stack(arrays, axis)

arrays相同形状的数组序列
axis:返回数组中的轴,输入数组沿着它来堆叠
a = np.array([[1,2],[3,4]])
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('\n')
print ('沿轴 0 堆叠两个数组:')
print (np.stack((a,b),0))
print ('\n')
print ('沿轴 1 堆叠两个数组:')
print (np.stack((a,b),1))
第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


沿轴 0 堆叠两个数组:
[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]


沿轴 1 堆叠两个数组:
[[[1 2]
  [5 6]]

 [[3 4]
  [7 8]]]

9.4.3 numpy.hstack
numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。

a = np.array([[1,2],[3,4]])
 
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
 
print ('第二个数组:')
print (b)
print ('\n')
 
print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
print ('\n')
第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


水平堆叠:
[[1 2 5 6]
 [3 4 7 8]]

9.4.4 numpy.vstack
numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。

a = np.array([[1,2],[3,4]])
 
print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])
 
print ('第二个数组:')
print (b)
print ('\n')
 
print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


竖直堆叠:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

9.5 分割数组

函数数组及操作
split将一个数组分割为多个子数组
hsplit将一个数组水平分割为多个子数组(按列)
vsplit将一个数组垂直分割为多个子数组(按行)

9.5.1 numpy.split
numpy.split 函数沿特定的轴将数组分割为子数组,格式如下:
numpy.split(ary, indices_or_sections, axis)

ary:被分割的数组
indices_or_sections:果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
axis:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分
a = np.arange(9)
 
print ('第一个数组:')
print (a)
print ('\n')
 
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('\n')
 
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
第一个数组:
[0 1 2 3 4 5 6 7 8]


将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]


将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

9.5.2 numpy.hsplit
numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。

harr = np.floor(10 * np.random.random((2, 6)))
print ('原array:')
print(harr)
 
print ('拆分后:')
print(np.hsplit(harr, 3))
原array:
[[4. 7. 6. 3. 2. 6.]
 [6. 3. 6. 7. 9. 7.]]
拆分后:
[array([[4., 7.],
       [6., 3.]]), array([[6., 3.],
       [6., 7.]]), array([[2., 6.],
       [9., 7.]])]

9.5.3 numpy.vsplit
numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。

a = np.arange(16).reshape(4,4)
 
print ('第一个数组:')
print (a)
print ('\n')
 
print ('竖直分割:')
b = np.vsplit(a,2)
print (b)
第一个数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]


竖直分割:
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]

9.6 数组元素的添加与删除
相关函数:
1.numpy.resize 函数返回指定大小的新数组。
2.numpy.append 函数在数组的末尾添加值。
3.numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
4.numpy.delete 函数返回从输入数组中删除指定子数组的新数组。
5.numpy.unique 函数用于去除数组中的重复元素。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值