矢量
矢量是指一堆形成的集合。
多维数组也叫做矢量化计算。
单独一个数叫做标量
例:
1 import datetime as dt
2 import numpy as np
3
4 n2=10000
5 start2 =dt.datetime.now()
6 A,B = [],[]
7
8 for i in range(n2):
9 A.append(i**2)
10 B.append(i**3)
11
12 C=[]
13
14 for a,b in zip(A,B): #zip()函数用于将可迭代的对象作为参数,将对象中的对应元素打包成一个元组,返回这些元组组成的列表
15 C.append(a+b)
16
17 print((dt.datetime.now()-start2).microseconds)
18
19 n=100000
20 start = dt.datetime.now()
21
22 C=np.arange(n)**2 + np.arange(n)**3
23 print(C)
24 print((dt.datetime.now()-start).microseconds)
25
26 '''
27 1.arange和python里range非常的相似
28 2.arange产生的也是一个连续的序列。序列的类型不再是列表,是数组array。
29 3.两数组可直接相加。
30 4.numpy内部完成循环。
31
32 '''
多维数组
1.Numpy对多维数组的定义:
用numpy.ndarray类。(n代表n个数,d代表dimision维度)。
Ndarray本身是一个类,由这个类实例化出来的对象,就是多维数组。
多维数组也是一个对象。
2.创建多维数组对象的方法:
1)numpy.arange(起始,终止,步长)
它是通过numpy来访问。是一个numpy里的函数。
它返回的数组是一个等差列的一维数组。
2)numpy.array()
这个array不是类。是一个numpy里函数。
在numpy.array()函数,括号里可以输入任何可被解释程数组的容器。(列表和元组。)
例:
1 import numpy as np
2 from numpy import pi
3
4 a = np.array([[1,1],
5 [0,1]])
6
7 b = np.array([[2,0],
8 [3,4]])
9
10 c = a * b
11 print(c)
12
13 #矩阵成集
14 c= a @ b
15 print(c)
16
17
18 print(a.dot(b))
19
20
21 a1 = np.ones((2,3),dtype=int)
22 b1=np.random.random((2,3))
23 a1*=3
24 print(a1)
25 print(b1)
26
27
28 a2=np.ones(3,dtype=np.int32)
29 b2=np.linspace(0,pi,3)
30 b2.dtype.name
31 print(b2.dtype)
32 c2=a+b
33 print(c2)
34 c2.dtype.name
35 d=np.exp(c2*1j)
36 print(d)
37 d.dtype.name
38
39
40 e1=1
41 e2=2
42 print(np.exp(e1))
43 print(np.exp(e2))
44
45
46 a4 = np.random.random((2,3))
47
48 print(a4)
49 print(a4.sum())
50 print(a4.min())
51 print(a4.max())
52
53
54 z =np.arange(12).reshape(3,4)
55 print(z)
56 print(z.sum(axis=0)) # 列的总和,0代表列
57 print(z.min(axis=1)) # 行的总和,1代表行
58 print(z.cumsum(axis=1)) #cumsum是指定行或者列,前数与现在的数字累加
获取数组元素类型的方法:
1:type([0][0]) =>python取类型的方法 方法
2:f.dtype =>numpy的方法 “int32”,代表4个字节的整型数。
为什么是int32?
原有是,在定义时未指定具体类型。而现在使用4个字节整形正好能保存f的数据,所以default缺省值就是4个字节。
3)查询结果的意义:
“<U1”的意义(输入字符串,用.dtype查询时):
1.Unicode每个编码占4个字节。有高低之分。分为小端序和大端序。
2.“U”代表是unicode编码。
3.“<”表示小端字节序。
4.“1”代表每个字符串里只有一个字符
“numpy.str”的含义(使用type(g[0] 查询时)):
1.“str”代表字符串。
2.“ ”和python作区分而加成的。
4)手动值定类型的写法: G=np.array(['1','2','3'].dtype=np.int32)
1.值要设置手动指定类型,它的数据类型就做自动转换了。虽然值是是字符串,但是我们给了指定目标类型是整形
2.场景:如果觉得还是字符串式好,还能用astype改回。
所有和类型转换有关的其实都不是类型转换,都是复制,都是按新类型在你复制一份,但是对于源是不变的 dtype是属性,取元素的类型。
3.关于维度的属性: shape属性的值是一个元组类型,一个元组内包含多个元素。分别是从高到低类表示他每一个维度的数。
思考:一个二位数组有行和列,行高还是列高?
如果有页 行 列
页:最高维度
行:次之
列:最低
4.areange和array都可以创建数组,有时候可以混用。
用shape属性可以看到维度。
Numpy中多用二维数组,三维很少用。
5.元素索引
元素索引是从0开始
数组[索引]
数组[行索引][列索引]
数组[页索引][行索引][列索引]或者[页索引,行索引,列索引]
Numpy的内置类型和自定义类型:
1.内置类型:
优点: 可显示占内存多少,可灵活变化
缺点: 因为具有灵活可变性,性能方面做出牺牲。(因需要留出足够多空间)。
无法使用固定内存地址的计算方法;
它只能用动态来完成,有关地址运算就要占用运用时间。
注:在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多字节的整数存在大小端序
对于多字节整数可以加上字节序前缀 前缀类型:(位数越低,地址越低)
“ ”<”,小端字节序,低数位低地址低。
“=”,系统默认,不能人为指定。由系统决定。
“>”,大端字节序,低数位高地址。
例子:
十六进制:0x1234
小端字节序:
L H
0x12 0x34
大端字节序:
L H
0x34 0x12
注:有时为了防止某个代码功能在不同处理器上取移植带来的一些兼容性问题。所以强制加上“<”或“>”
4.关于字节序:
不需添加字节序的数据类型:
单字节整数
布尔值
复数类型
浮点型
其他情况:
Numpy.str =>U+字符数
Unicode 本身就是多字节整正
一个unicode可看作一个uint32,它也存在大小端字节序
Numpy.bool =>b
注:numpy提供的是python的封装,用自定义类型方法可以完成一个元素不同类型的访问;
或者一个元素用不同类型类组合,弥补了numpy数组元素同质的情况。
切片
与python相似
数组[起始:终止:步长]
可以针对多维数组来切片
缺省起始:首元素(步长为正),尾元素(步长为负)->逆向
缺省终止:尾后(步长为正),首前(步长为负)
缺省步长:一个或者一个以上缺省值切片。
a[...]连续或者几个连续的维度使用缺省切片,用‘...’表示
例:
1 import numpy as np
2
3 a = np.arange(1,10)
4 print(a)
5
6 print(a[:3])
7 print(a[3:6])
8 print(a[6:])
9 print(a[::-1])
10
11
12 print(a[:-4:-1])
13 print(a[4:7:1])
14 print(a[-7::-1])
15 print(a[::])
16 print(a[...])
17 print(a[:])
18 # print(a[]) #行不通 error
19 print(a[::3])
20 print(a[1::3])
21 print(a[2::3])
22
23
24
25 b=np.arange(1,25).reshape(2,3,4)
26 print(b)
27 print("="*120)
28 print(b[:,0,0])
29 print(b[0,:,:])
30 print(b[0,...])
31 print(b[0,1,::2])
32 print(b[:,1:,1])
33 print(b[1,1,1])
34 print(b[1,1::2,1])
View Code
改变维度
分为四种方式:
1)视图变维
针对一个数组对象获取不同维度的视图
方法:数组.reshape(新维度) ->数组新维度视图
数组.ravel() ->数组的一维视图
2)复制变维(不同维度的拷贝)
针对一个数组对象获取其不同维度的副本。
方法:flatten() ->数组的一维副本。
功能:在获得原数据实例的同时获得了拷贝,也就是副本。
3)就地变维
数组.shape=(新维度)
等价于
数组.resize(新维度)
4)视图转置(线性代数的概念)
可理解为行列互换
数组.transpose() ->数组的转置视图
等价于
数组.T ->转置视图属性
一般用数组.T的方式
注:转置必须是二维的
例:
1 import numpy as np
2
3 a = np.arange(1,9)
4 print(a)
5
6 print("=" *120)
7 b=a.reshape(2,4)
8
9 print(b)
10
11 c= b.reshape(2,2,2)
12 print(c)
13
14 d = c.ravel()
15 print(d)
16 print("_"*120)
17 e= c.flatten()
18 print(e)
19
20
21 print("_"*120)
22 f=b.reshape(2,2,2).copy()
23 print(f)
24
25
26
27 print("+"*120)
28 a+=10
29 print(a,b,c,d,e,f,sep="\n")
30 print("+"*120)
31 a.shape=(2,2,2)
32 print(a)
33
34 a.resize(2,4)
35 print(a)
36
37
38
39
40 print("W"*120)
41 g=a.transpose()
42 print(g)
43
44 print("D"*123)
45 g=a.T
46 print(g)
47
48 print(np.array([e]),1) #先转成多维数组再转置
49 print(e.reshape(-1,1)) #输入-1这个无效值
组合和拆分
1.垂直组合
numpy.vstack((上,下))
垂直拆分
numpy.vsplit(数组,份数)
例:a,b = np.vsplit(c,2)
c代表是被拆的变量,2代表拆分成2份
2.水平组合
numpy.hstack((左,右))
水平拆分
numpy.vsplit(数组,份数)
例:a,b = np.hsplit(c,2)
c代表是被拆的变量,2代表拆分成2份
3.深度组合和深度拆分
numpy.dstack((前,后))
numpy.dsplit((数组,份数))
深度组合:
1是前后布局,用第三个垂直于平面来截线,截到这部分以数组形式组合起来,构成一个三位数组
2这三个截面试三个页面,每个页面上都有一个二维数组来自于所对应的行,同时还做了转置,截到的行转成列。
深度拆分:
a,b=np.dsplit(c,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((左,右))简略写法:c=np.c_[a,b]
回顾:ndarray属性:
dtype元素类型
Shape数组维度
T转置视图
nidm维度数
size元素数。仅对一堆数组等价于python的len()
len()永远得到shape里的第一个元素
* size得到的都是shape里的乘积
nbytse总字节数
itemsize 元素的字节数 即一个元素占多少字节
flat 扁平化迭代器(得到的是一个迭代器对象,可以进行迭代遍历)
tolist 数组改列表
real 实部数组
imag 虚部数组
·* numpy也有append函数方法,但是必须有返回值。
例: x=np.append(x,50)
print(x)
1 import numpy as np
2
3 a=np.array([
4 [1+1j,2+4j,3+7j],
5 [4+2j,5+5j,6+8j],
6 [7+3j,8+6j,9+9j]
7 ])
8
9 print(a.dtype) #complex128 128位 16个字节 8字节代表实部 8字节代表虚部
10 print(a.shape) #(3,3)3行3列
11 print(a.ndim) #2 2维
12 print(a.size,len(a)) #9个元素 3行*3列=9;len返回3,3行 shape元组里第一个元素
13 print(a.itemsize) #16每个元素占16个字节
14 print(a.nbytes) #144字节 16*9
15 print(a.T)
16 print(a.real,a.imag,sep='\n') #取实部和虚部
17 for elem in a.flat: #flat就是一个扁平迭代器,相比ravel,flatten不需要占有额外内存,空间效率更高
18 print(elem)
19
20 print(a.flat[[1,3,5]])#只取1 3 5 号元素
21 a.flat[[2,4,6]] = 0 #还可以修改元素
22 print(a)
23
24 def fun(a,b):
25 a.append(b)
26 return a
27
28 x =np.array([10,20,30])
29 y=40
30 # x-fun(x,y) #报错,因为数组没有append的方法
31 # x = fun(x.tolist(),y) #改成了列表
32 x=np.array(fun(x.tolist(),y)) #这样还是数组
33 print(x)
34
35 y=np.append(x,50)
36 print(y)