人工智能入门--Numpy

一 矢量

矢量是指一堆数形成的集合

​ 多维数组也叫做矢量化计算

​ 单独一个数叫做标量

二 多维数组

  1. numpy 对多维数组的定义:

​ 用numpy.ndarray类 (n代表n个数,d代表dimision维度)

​ Ndarray本身是一个类, 由这个类实例化出来的对象,就是多维数组

​ 多维数组也是一个对象

  1. 创建多维数组对象的方法:

    1> numpy.arange(起始,终止,步长)

    ​ 他是通过numpy来访问. 是一个numpy里的函数

    ​ 它返回的数组是一个等差数列的一维数组

    2> numpy.array()

    ​ 这个array不是类,是numpy里的函数

    ​ 在numpy.array() 函数的括号里,可以输入任何可被解释成数组的容器,(列表或元组)

    3> 获取数组元素类型的方法:

    d = np.array([[1,2,3],[4,5,6]])
    方法一: type(d[0][0])  #==>python取类型的方法
    方法二: d.dtype  #==> numpy 取类型的方法

    4> int 32代表4个字节的整数型

    ​ 为什么是int32?

    ​ 在定义时未指定具体类型,而现在使用4个字节整形正好能保存d的数据,

    ​ 所以default缺省值就是4个字节..

    5> <U1 的意义

    g=np.array(['1','2','3'])
    print(g.dtype)    # <U1
    print(type(g[0]))  #<class 'numpy.str_'>
    • ​ Unicode 每个编码占4个字节. 由高低之分. 分为小端序和大端序
    • ​ 'U' 代表是 unicode编码
    • ​ '< ' 表示小端序
    • ​ '1' 代表每个字符串中只有一个字符

    6> 'numpy.str_' 的含义

    • ​ str 代表字符串
    • ​ _ 和python的字符串作为区分

    7> 手动指定类型的写法

    G=np.array(['1','2','3'],dtype=np.int32)
    print(G.dtype)  #int32
    H=G.astype(np.str_)
    print(H.dtype)  #<U11
    • ​ '只要设置手动指定类型,它的数据类型就做自动转换了.虽然值是字符串,但是我们指定目标类 型是整形int32,所以它的类型是int 32'
    • ​ 场景: 若要改回字符串格式,用 astype 函数
    • ​ <U11 解释: 类型被再次改回来时,内存中回预留一些空间,

​ 注: 所有和类型转换有关的其实都不是类型转换,都是复制,然后按新的类型复制一份, 但是 ,源是 不变的

​ dtype 是属性 ,用来取元素的类型

​ 8> 关于维度的属性

d = np.array([[1,2,3],[4,5,6]])
print(d.shape)  #(2, 3)  2行 3列
  • ​ shape属性 :

​ shape属性的值是一个元组类型,一个元组内包含多个元素,分别是从高到低来表示每个维度 的数.. 即 高纬度 到 低纬度

​ 如果有 页 行 列

​ 页: 最高维度

​ 行: 次之

​ 列: 最低

​ 9> arrange 和 array 都可以创建数组,有时候可以混合用

i = np.array([[np.arange(1,5),np.arange(5,9),np.arange(9,13)],[np.arange(13,17),np.arange(17,21),np.arange(21,25)]])
print(i)
# [[[ 1  2  3  4]
#   [ 5  6  7  8]
#   [ 9 10 11 12]]
# 
#  [[13 14 15 16]
#   [17 18 19 20]
#   [21 22 23 24]]]

​ 用shape属性可以看到维度

​ Numpy 中多用二维数组,三维很少用

​ 10> 元素索引

元素索引是从 0  开始的

数组[索引]
数组[行索引][列索引]
数组[页索引][行索引][列索引]

a=np.array([[[ 1  ,2 , 3  ,4], [ 5  ,6 , 7 , 8], [ 9 ,10 ,11 ,12]]])
print(a[0])   #[[ 1  ,2 , 3  ,4], [ 5  ,6 , 7 , 8], [ 9 ,10 ,11 ,12]]
print(a[0][0])   # [1 2 3 4]
print(a[0][0][0])  # 1

for i in range(a.shape[0]):  # 0 是逐页
    for j in range(a.shape[1]): # 1 是逐行
        for k in range(a.shape[2]):   # 2 是逐列
            print(a[i][j][k])

三 Numpy的内置类型和自定义类型

  1. 内置类型

    ​ a) 优点:
    ​ 可指定数据类型所占内存是多少
    ​ 可灵活变化
    ​ b) 缺点:
    ​ 因为具有灵活可变性, 所以会牺牲性能, (需要留出足够空间)
    ​ 无法使用固定内存地址的计算方法, 只能用动态完成, 因为有关地址的运算就会占用运行时间
    ​ 注: 在numpy里为每一种类型提供了固定的大小,所以有关地址运算完全可以通过类型来确定. Numpy定义了一套自己独立的数据类型体系.. 数据类型有固定的长度,字节数都是固定的..
    ​ 例 : Numpy.bool 一个布尔占一个字节
    ​ 有符号版本( 正负数 ):
    ​ Int8 1字节 有符号类型
    ​ Int16 2字节 有符号类型
    ​ Int32 4字节 有符号类型
    ​ 无符号版本( 只有正数 ):
    ​ Uint8 1字节 无符号类型
    ​ Uint16 2字节 无符号类型
    ​ Uint32 4字节 无符号类型
    ​ 浮点类型:
    ​ Float16 2字节 浮点型 有符号
    ​ Float32 4字节 浮点型 有符号
    ​ Float64 8字节 浮点型 有符号
    ​ 复数类型( 实部和虚部都用2个4字节浮点型表示 ):
    ​ Complex64 8字节 复数类型
    ​ Complex128 16字节 复数类型
    ​ 注: 1复数 = 2个浮点型的组合
    ​ 字符串类型:
    ​ Str_ 字符串没有规定多少字节, 因为字符串类型取决与字符串 unicode 的长度
    ​ 字符串的长度根据字符串包含的字符决定
    ​ 注: lunicode = 4 个字节
    ​ 可以用 dtype 和 astype 来设置类型转换

  2. 自定义类型

    1. ​ 直接使用内置类型的原始名

    2. ​ 使用紧凑类型格式 ( 类型编码字符串 )
      ​ 简化操作: 可以用更少的字符串来表示

      全称 简化格式
      Numpy.int8 i1
      Int16 i2
      Uint32 U4
      Float64 F8
      Complex128 c16
    3. 多字节的整数存在大小端序
      多字节整数可以加上字节序前缀
      前缀类型 :
      '<' 小端序 低数位 低地址
      '=' 系统默认, 不能人为指定
      '>' 大端序 低树位 高地址

      注: 有时为了防止因某个代码功能在不同处理器上移植带来的兼容性问题,所以强制加上了'< ' 和 '> '

      import numpy as np
      
      a=np.array([('ABC',[1,2,3])],dtype={'names':['name','scores'],'formats':['U3','3i4']})
      print(a)  #[('ABC', [1, 2, 3])]
      print(a[0]['name'])   #ABC
      print(a[0]['scores'][0])  #1
      print(a[0]['scores'][1])    #2
      print(a[0]['scores'][2])    #3
      

b=np.array([0x1234],dtype=('u2',{'低数位':('u1',0),'高数位':('u1',1)})) # 大端序
print('{:x}'.format(b[0])) #以16进制输出b里的第0号元素
print('{:x},{:x}'.format(b['低数位'][0],b['高数位'][0]))
```

  1. 关于字节序:

    ​ 不需添加字节序的数据类型: 单字节整数, 布尔值, 复数类型, 浮点数

    ​ 其他情况: Numpy.str_ => U+字符数

    ​ Unicode 本身就是多字节整数, 一个unicode可看作一个uint32,也存在大小端序

    ​ Numpy.bool => b

    ​ 注: numpy提供的是python的封装, 用自定义类型的方法可以完成一个元素不同类型的访问; 或把一个元素用不同类型来组合,弥补了numpy数组元素同质的情况..

四 切片

​ 与python相似

​ 数组[起始: 终止: 步长]

​ 可以针对多维数组来切片

​ 缺省起始: 首元素( 步长为正 ) , 尾元素( 步长为负 ) ->逆向

​ 缺省终止: 尾后( 步长为正 ) , 首前( 步长为负 )

​ 缺省步长: 1

a = np.arange(1,10)
print(a)  #[1 2 3 4 5 6 7 8 9]
print(a[:3])   #[1 2 3]
print(a[3:6])  #[4 5 6]
print(a[6:])   #[7 8 9]
print(a[:-4:-1])  #[9 8 7]
print(a[...])    #[1 2 3 4 5 6 7 8 9]
print(a[:])    #[1 2 3 4 5 6 7 8 9]
print(a[1::3])  #[2 5 8]

b=np.arange(1,25).reshape(2,3,4)
print(b)
# print(b[:,0,0])  # [ 1 13]
# print(b[0,:,:])
# print(b[0,1,::2])  #[5 7]
# print(b[-1,1:,2:])
# print(b[:,1:,1])
print(b[1,1,::2])  #[17 19]

​ 一个或一个以上缺省值切片:

​ a[...] a[ : ]

五 改变维度

​ 分为 4 种方式

  1. ​ 视图变维 :

    ​ 针对一个数组对象获取不同维度的视图

    ​ 方法: 数组.reshape(新维度) -> 数组新维度视图

    ​ 数组.ravel() -> 数组的一维视图

    import numpy as np
    
    a=np.array([np.arange(1,9)])
    print(a)   #[[1 2 3 4 5 6 7 8]]
    
    b=a.reshape(2,4)
    print(b)   #[[1 2 3 4] [5 6 7 8]]
    
    c=b.ravel()
    print(c)   #[1 2 3 4 5 6 7 8]
  2. 复制变维度 ( 不同维度的拷贝 ):
    针对一个数组对象获取不同维度的副本
    方法: flatten() -> 数组的以为副本
    功能: 在获得原数据实例的同时获得拷贝, 也就是副本

    d=b.flatten()
    print(d)   #[1 2 3 4 5 6 7 8]  复制成一维
    
    e=b.reshape(2,2,2).copy()
    print(e)
  3. 就地变维
    数组. shape = ( 新维度 )
    等价于
    数组. resize( 新维度 )

    a=np.array([np.arange(1,9)])
    a.shape = (2,2,2)
    # a.resize =(2,2,2) 
    print(a)  #变成一个新的2页2行2列的三维数组
  4. 视图转置 ( 线性代数的概念 )
    可理解为行列互换
    数组. transpose( ) ->数组的转置视图
    等价于

    ​ 数组. T -> 转置视图属性

    a=np.array([np.arange(1,9)])
    a.shape = (4,2)  #a是4行2列
    g = a.transpose()
    print(g)
    # [[1 3 5 7]
    #  [2 4 6 8]]
    
    print(np.array([a]).T)  #先转成多维数组,再转置
    print(a.reshape(-1,1))   # -1 无效值

    ​ 注: 装置必须是二维的数组才可以

    六 组合和拆分

    • ​ 垂直组合 :

    ​ numpy.vstack( ( 上 下) ) 栈

    • ​ 垂直拆分 :

    ​ numpy.vsplit( 数组 , 份数 )

    ​ 列: a,b=np.vsplit( c , 2 )

    ​ c 代表是被拆的变量 2 代表的是拆分成2 份

    import numpy as np
    
    a=np.arange(11,20).reshape(3,3)
    print(a)
    b=np.arange(21,30).reshape(3,3)
    print(b)
    c=np.vstack((a,b))
    print(c)
    
    l,h=np.vsplit(c,2)
    print(l,h,sep='\n')  #把c 拆分成 l 和 h 两个
    • ​ 水平组合 :

    ​ numpy.hstack( ( 左 右) ) 栈

    • ​ 水平拆分 :

    ​ numpy.hsplit( 数组 , 份数 )

    ​ 列: a,b=np.vsplit( c , 2 )

    ​ c 代表是被拆的变量 2 代表的是拆分成2 份

    import numpy as np
    
    a=np.arange(11,20).reshape(3,3)
    print(a)
    b=np.arange(21,30).reshape(3,3)
    print(b)
    c=np.hstack((a,b))
    print(c)
    l,h=np.hsplit(c,2)
    print(l,h,sep='\n')
    • 深度组合 和 深度拆分

      numpy.dstack( ( 前 后 ) ) 栈

      numpy.dsplit( 数组 , 份数 )

    c=np.dstack((a,b))
    print(c)
    l,h=np.dsplit(c,2)
    print(l,h,sep='\n')

    深度组合:

    1. 前后布局,用第三个垂直于平面来截线 , 截到的这部分就以数组的形式组合起来, 构成一个 三位数组
    2. 这三个截面就是三个页 , 每个页 都有一个二维数组来自于对应的行 , 同时还做了转置 , 截到的行转为列

    深度拆分:

    1. a, b = np.dsplit( c , 2)

    2. print( a.T [ 0 ] . T , b.T [ 0 ] . T ,sep='\n') #T [ 0 ] . T转置取0号元素再转置

      注: 深度拆分 如要恢复成二维数组的样式,需手工来操作

      行 / 列 组合

    3. ​ 特点: 只能组合不能拆分

      ​ numpy.row_stack( ( 上 下 ) ) 等价于 numpy.vstack

      ​ numpy.column_stack( ( 左 右 ) ) 等价于 numpy.hstack

      ​ numpy.column_stack( ( 左 右 ) ) 简略写法 np.c_[左 右]

七 回顾 ndarray属性

  • dtype 元素类型
  • shape 数组维度
  • T 转置视图
  • ndim 维度数
  • size 元素数 . 针对一维数组 等价于python的 len()
  • npytes 元素的总字节数
  • len () 永远得到shape里的第一个元素 *** size** 得到的是shape里的乘积
  • itemize 元素的字节数 即一个元素占多少字节
  • flat 扁平迭代器 得到的是一个迭代对象 ,可以进行迭代遍历
  • tolist 数组改列表
  • imag 虚部数组
  • real 实部数组

*****numpy也有append 函数方法 ,但是必须有返回值

import numpy as np

a=np.array([
    [1+1j,2+4j,3+6j],
    [1+1j,2+4j,3+6j],
    [1+1j,2+4j,3+6j]
])
print(a.dtype)  #complex128 16个字节 8位是实部 8位是虚部
print(a.shape)   #3行3列
print(a.ndim)    #2维
print(a.size,len(a))   # 9个元素  3 列
print(a.itemsize)  # 每个元素占16个字节
print(a.nbytes)  # 144个字节  16* 9
print(a.T)
print(a.real,a.imag,sep='\n')   # 取实部和虚部
for i in a.flat:   #flat 扁平迭代器
    print(i)
# ----------------------------------------------------------
#列 :
def fun(z,zz):
    z.append(zz)
    return z
x=np.array([1,2,3])
y=40
# x=fun(x,y) #会报错 因为数组没有append方法
x=fun(x.tolist(),y)
print(x)  #[1, 2, 3, 40]

y=np.append(x,50)
print(y)    #[ 1  2  3 40 50]

猜你喜欢

转载自www.cnblogs.com/clove7/p/11536347.html