【漫漫转码路】Python Day 25

Numpy

1、从形状或数值创建

(1)empty和empty_like

np.empty(shape, dtype=np.float64):创建指定形状的数组,默认类型是float64,数组里面不是空,只是没有初始化,数据随机(因为数组是固定的,创建完成之后不能伸缩,不能改变改变数据数量)
np.empty_like(prototype, dtype=None):prototype上传array_like,返回形状与类型与prototype一致的数组,没有初始化

# 例如
import numpy as np
np1 = np.empty((1, 2, 3))
print(np1)

np2 = np.empty_like(np1)
print(np2)
print(np2.dtype)
# 终端显示
[[[9.23592996e-143 2.31513056e-313 4.85213860e-308]  # 没有初始化
  [5.39198960e+067 3.86093052e+228 2.42899930e-313]]]
[[[9.23592996e-143 2.31513056e-313 4.85213860e-308]  # 没有初始化
  [5.39198960e+067 3.86093052e+228 2.42899930e-313]]]
float64  # 类型与原数据一致

(2)zeros和zeros_like

np.zeros(shape, dtype=np.float64):创建指定形状的数组,默认类型是float64,数组里面初始化为0
np.zeros_like(prototype, dtype=None):prototype上传array_like,返回形状与类型与prototype一致的数组,初始化为0

# 例如
import numpy as np
np1 = np.zeros((1, 2, 3))
print(np1)

list = [1, 2, 3, 4]
np2 = np.zeros_like(list)
print(np2)
print(np2.dtype)
# 终端显示
[[[0. 0. 0.]
  [0. 0. 0.]]]  # 全都是0
[0 0 0 0]  # 全都是0
int32  # 类型自推断

(3)ones和ones_like

np.ones(shape, dtype=np.float64):创建指定形状的数组,默认类型是float64,数组里面初始化为1
np.ones_like(prototype, dtype=None):prototype上传array_like,返回形状与类型与prototype一致的数组,初始化为1

# 例如
import numpy as np
np1 = np.ones((1, 2, 3))
print(np1)

list = [1, 2, 3, 4]
np2 = np.ones_like(list)
print(np2)
print(np2.dtype)
# 终端显示
[[[1. 1. 1.]
  [1. 1. 1.]]]  # 初始化为1
[1 1 1 1]
int32

(4)full和full_like

np.full(shape, fill_value, dtype = None):创建指定形状的数组,默认类型是float64,数组里面初始化为fill_value;
np.full(prototype, fill_value, dtype = None):prototype上传array_like,返回形状与类型与prototype一致的数组,初始化为1

# 例如
import numpy as np
np1 = np.full((1, 2, 3), 8)  # 指定初始化填充为8
print(np1)

list = [1, 2, 3, 4]
np2 = np.full_like(list, 8)  # 指定填充为8
print(np2)
print(np2.dtype)
# 终端显示
[[[8 8 8]
  [8 8 8]]]
[8 8 8 8]
int32

(5)eye和identity

np.eye(N, M=None, k=0, dtype=np.float64):创建一个N行M列,对角线为1,其余为0的单位矩阵,列数M默认为行数,k=0是对角线,可以上移或下移,k为正数表示上移,k为负数表示下移,默认类型是float64
np.identity(n, dtype=np.float64):创建一个n行n列,对角线为1其余为0的单位矩阵,默认类型float64

# 例如
import numpy as np
np1 = np.eye(4)
print(np1)
np1 = np.eye(4, k=1)
print(np1)
np1 = np.eye(4, 8)
print(np1)
# 终端显示
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]  # 4*4的矩阵,对角线是1,其余是0
[[0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]]  # 4*4的矩阵,对角线上移1
[[1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0.]]  # 当生成举证不是方阵的时候,以最短边形成一个方阵,这里就是4*4
# 例如
import numpy as np
np1 = np.identity(4)
print(np1)
# 终端显示
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

2、从数值范围创建

(1)arange和reshape

np.arange([start,]stop[, step,],dtype=None):返回给定区间(左闭右开)的均匀间隔值构成的数组,基本用法和range一样,但是可以是小数
通常和reshape一起用
np.reshape(a, newsshape):将类数组a,转换成形状为newshape的数组

# 例如
import numpy as np
np1 = np.arange(0, 10, 2)
print(np1)
np1 = np.arange(0, 10)
print(np1)
np1 = np.arange(10)
print(np1)
np3 = np.arange(1.2, 10.2, 2.1)
print(np3)

np2 = np.reshape(np1, (2, 5))
print(np2)
# 终端显示
[0 2 4 6 8]  # [0,10)间隔为2
[0 1 2 3 4 5 6 7 8 9]  # [0,10)默认间隔为1
[0 1 2 3 4 5 6 7 8 9]  
[1.2 3.3 5.4 7.5 9.6]  # 这里start,stop和step都可以是小数
[[0 1 2 3 4]  # 改变成(2,5)的形状
 [5 6 7 8 9]]

(2)linspace

np.linspace(start, stop, num=50, endpoint=True, retset=False, dtype=None):在创建一个以start开始,以stop结束,默认值为50个的等差数列,endpoint表示是否包含stop,默认True表示包含,retset表示是否返回步长,默认不返回,如果要返回,以元组形式返回步长
永远不会是整数,除非手动限制改变类型,如果改变成整型之后,是直接对原数据求int

# 例如
import numpy as np
np1 = np.linspace(0, 50)
print(np1)
np1 = np.linspace(0, 50, dtype=np.int32)
print(np1)

np1 = np.linspace(0, 10, 20)
print(np1)
np1 = np.linspace(0, 10, 20, dtype=np.int32)
print(np1)

np1 = np.linspace(0, 10, 20, False)
print(np1)
np1 = np.linspace(0, 10, 20, False, True)
print(np1)
# 终端显示
[ 0.          1.02040816  2.04081633  3.06122449  4.08163265  5.10204082  # 0到50,默认包含50,默认50个数,结果是浮点型
  6.12244898  7.14285714  8.16326531  9.18367347 10.20408163 11.2244898
 12.24489796 13.26530612 14.28571429 15.30612245 16.32653061 17.34693878
 18.36734694 19.3877551  20.40816327 21.42857143 22.44897959 23.46938776
 24.48979592 25.51020408 26.53061224 27.55102041 28.57142857 29.59183673
 30.6122449  31.63265306 32.65306122 33.67346939 34.69387755 35.71428571
 36.73469388 37.75510204 38.7755102  39.79591837 40.81632653 41.83673469
 42.85714286 43.87755102 44.89795918 45.91836735 46.93877551 47.95918367
 48.97959184 50.        ]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  # 手动调整成为整型之后可以显示整型
 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 48 50]
[ 0.          0.52631579  1.05263158  1.57894737  2.10526316  2.63157895  # 0到10,取20个数,显示浮点型
  3.15789474  3.68421053  4.21052632  4.73684211  5.26315789  5.78947368
  6.31578947  6.84210526  7.36842105  7.89473684  8.42105263  8.94736842
  9.47368421 10.        ]
[ 0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9 10]  # 调整为整型之后可以发现是对原数据直接取整,不是四舍五入
[0.  0.5 1.  1.5 2.  2.5 3.  3.5 4.  4.5 5.  5.5 6.  6.5 7.  7.5 8.  8.5  # 0到10取20个数,不包括20
 9.  9.5]
(array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. ,  # 返回步长,最后的就是步长
       6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5]), 0.5)  # 这玩意儿是个列表,还不是数组

(3)logspace

np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):创建一个以(basestart)为起始,(basestop)为终点,默认为50个,默认包含(base**stop),默认base是10.0的等比数列

# 例如
import numpy as np
np1 = np.logspace(2, 3)
print(np1)
np1 = np.logspace(2, 3, 10)
print(np1)
np1 = np.logspace(2, 3, 10, False)
print(np1)
np1 = np.logspace(2, 3, 10, False, 2)
print(np1)
np1 = np.logspace(2, 3, 10, False, 2, np.int32)
print(np1)
# 终端显示
[ 100.          104.81131342  109.8541142   115.13953993  120.67926406  # 100到1000,50个数
  126.48552169  132.57113656  138.94954944  145.63484775  152.64179672
  159.98587196  167.68329368  175.75106249  184.20699693  193.06977289
  202.35896477  212.09508879  222.29964825  232.99518105  244.20530945
  255.95479227  268.26957953  281.1768698   294.70517026  308.88435965
  323.74575428  339.32217719  355.64803062  372.75937203  390.69399371
  409.49150624  429.19342601  449.8432669   471.48663635  494.17133613
  517.94746792  542.86754393  568.9866029   596.36233166  625.05519253
  655.12855686  686.648845    719.685673    754.31200634  790.60432109
  828.64277285  868.51137375  910.29817799  954.09547635 1000.        ]
[ 100.          129.1549665   166.81005372  215.443469    278.25594022  # 100到1000,10个数
  359.38136638  464.15888336  599.48425032  774.26368268 1000.        ]
[100.         125.89254118 158.48931925 199.5262315  251.18864315   # 100到1000,10个数,不包含1000
 316.22776602 398.10717055 501.18723363 630.95734448 794.32823472]
[4.         4.28709385 4.59479342 4.92457765 5.27803164 5.65685425  # 4到8,10个数,不包含8
 6.06286627 6.49801917 6.96440451 7.46426393]
[4 4 4 4 5 5 6 6 6 7]  # 4到8,10个数,不包含8,int32类型

3、基本运算

数组的基本运算都是逐元素运算

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]
list2 = [[1, 1], [2, 2], [3, 3]]
np1 = np.array(list1)
np2 = np.array(list2)
print(f'加\n{np1 + np2}')
print(f'减\n{np1 - np2}')
print(f'乘\n{np1 * np2}')
print(f'除\n{np1 / np2}')
print(f'取整\n{np1 // np2}')
print(f'取余\n{np1 % np2}')
print(f'大于\n{np1 > np2}')  # 会将每个数据进行bool判断,返回bool值
print(f'小于\n{np1 < np2}')
print(f'等于\n{np1 == np2}')
# 终端显示[[2 3]
 [4 5]
 [6 7]][[0 1]
 [0 1]
 [0 1]][[ 1  2]
 [ 4  6]
 [ 9 12]][[1.         2.        ]
 [1.         1.5       ]
 [1.         1.33333333]]
取整
[[1 2]
 [1 1]
 [1 1]]
取余
[[0 0]
 [0 1]
 [0 1]]
大于
[[False  True]
 [False  True]
 [False  True]]
小于
[[False False]
 [False False]
 [False False]]
等于
[[ True False]
 [ True False]
 [ True False]

如果两个数组形状不一样,在满足一定条件之后也可以进行基本运算
见《广播机制》

4、广播机制

后缘维度:当两个数组形状不一样,以形状短的数组为标准(及维度低的数组),从后往前来判断,如果维度低的数组的形状和维度高的数组的形状,在后面几个都一样的话,就会自动进行广播,就可以进行运算

# 例如
import numpy as np
a = np.arange(24).reshape(2, 3, 4)
b = np.arange(12).reshape(3, 4)
print(a+b)
# 此时(2, 3,4)和(3, 4),(3,4)就是后缘维度,后缘维度一致,那么可以广播,可以进行运算
# 终端显示
[[[ 0  2  4  6]
  [ 8 10 12 14]
  [16 18 20 22]]

 [[12 14 16 18]
  [20 22 24 26]
  [28 30 32 34]]]

后缘维度中,1可以代表任何数字

# 例如
import numpy as np
a = np.arange(24).reshape(2, 3, 4)
b = np.arange(4).reshape(1, 4)
print(a+b)
# 终端显示
[[[ 0  2  4  6]
  [ 4  6  8 10]
  [ 8 10 12 14]]

 [[12 14 16 18]
  [16 18 20 22]
  [20 22 24 26]]]
 # 会把b广播成三份,形成
 '''
 [[ 0  1  2  3]
  [ 0  1  2  3]
  [ 0  1  2  3]]
 '''
 # 然后广播2份,形成
  [[[ 0  1  2  3]
    [ 0  1  2  3]
    [ 0  1  2  3]]
   [[ 0  1  2  3]
    [ 0  1  2  3]
    [ 0  1  2  3]]]
# 然后进行相加

5、索引和切片

数组是可迭代对象

(1)索引和切片特点

数组的索引会复制数据,不是视图,
但是切片不会复制数据,是视图
数组支持多维数组的多维切片

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]
np1 = np.array(list1)
print(np1)
print('索引')
test1 = np1[0][0]
print(f'改之前\n{test1}')
np1[0][0] = 7
print(f'改之后\n{test1}')
print(np1)
print('切片')
test2 = np1[:1]
print(f'改之前\n{test2}')
np1[:1] = [33, 44]
print(f'改之后\n{test2}')
print(np1)
# 终端显示
[[1 2]
 [2 3]
 [3 4]]
索引
改之前
1
改之后  # 可以看到,更改之后,索引没有发生变化
1
[[7 2]
 [2 3]
 [3 4]]
切片
改之前
[[7 2]]
改之后
[[33 44]]  # 可以发现,改完之后,发生了变化,切片是视图
[[33 44]
 [ 2  3]
 [ 3  4]]

索引会降维,切片不会降维

(2)多维数组的多维索引

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
print(np1[1, 0])  # 这种也可以索引
# 多维数组索引思维
# (1,0)分别对应形状的两个轴,1对应3,2维数组里面有3个一维数组,里面取1,也就是[2, 3],然后0对应2,每个1维数组里面有2个标量,从里面取0,也就是2
print(np1[:2, 1:2])
# 多维数组切片思维
# [:2][1:2]分别对应(3, 2),对0轴,也就是3,进行切片[:2],得到[[1, 2], [2, 3]]
# 然后对1轴,也就是2,进行切片,[1:2],每个数组取[1:2],分别得到2和3,由于切片不降维,这次切片得到的是[2]和[3],因此最终结果是[[2] [3]]
# 终端显示
2
[[2]
 [3]]

(3)数组索引 / 整数索引

特点,1个列表
数组索引里面传一个列表,将列表的每个元素进行索引,得到的数组升一个维度组合成一个数组

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
print(np1[[1, 2]])
# 相当于np1[1],也就是 [2, 3],和np1[2],也就是[3, 4],升维组成一个数组[[2 3] [3 4]]
# 终端显示
[[2 3]
 [3 4]]

不会降维

(4)花式索引

类似于拉链操作
特点,2个列表
将每个列表的第1个拿出来组成索引,分别用数组进行索引,得到数据,然后都拿出来第二个,用数组进行索引,得到第二个数据,以此类推,将最终的结果用数组表示

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
print(np1[[1, 0, 0], [0, 1, 0]])
# np1[1, 0]=2
# np1[0, 1]=2
# np1[0, 0]=1
# 三个数据组成数组[2, 2, 1]
list1 = [[[1, 2], [2, 3], [3, 4]], [[3, 4], [2, 3], [1, 2]]]
np1 = np.array(list1)
print(np1[[1, 0, 0], [0, 1, 0]])
# np1[1, 0]=[3, 4]
# np1[0, 1]=[2, 3]
# np1[0, 0]=[1, 2]
# 然后升维组成数组
# 终端显示
[2 2 1]
[[3 4]  # 结果不一定是一维的
 [2 3]
 [1 2]]

(5)布尔索引

特点:有True或False
将对应的False去掉,留下True

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
print(np1[[True, False,True]])
# [1, 2]对应True
# [2, 3]对应False
# [3, 4]对应True
print(np1[np1 > 2])
# 大于小于号本质也是bool索引,将里面元素进行bool判断,大于2是True,否则是False,然后将True留下,False去掉,并将元素组成一维数组
# 终端显示
[[1 2]
 [3 4]]
[3 3 4]

最终形成一维数组

注意:
无论什么方式的切片索引,
切片不降维,索引降维,
如果在1维处索引,则1维降成标量,最后结果是[5 9]
如果在1维处切片,则不降维,结果是[5][9]
在哪个轴索引,则降哪里的维

6、常用操作(部分)

(1)resize

np.resize(a, new_shape):将a返回具有指定形状的新数组
ndarray.resize(new_shape):返回具有指定形状的新数组

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
np1.resize(3, 3)
print(np1)
np1.resize(1, 3, 3)
print(np1)
# 终端显示
[[1 2 2]
 [3 3 4]
 [0 0 0]]
 [[1 2 2]
 [3 3 4]
 [0 0 0]]
[[[1 2 2]
  [3 3 4]
  [0 0 0]]]

inplace操作,无返回值
允许数组size发生变化,返回数据不可控,会自动广播,不知道会广播成什么样子

(2)flatten

ndarray.flatten():扁平化回到一维数组

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
np1.resize(3, 3)
print(np1)
np1.resize(1, 3, 3)
print(np1)
print(np1.flatten())
# 终端显示
[[1 2 2]
 [3 3 4]
 [0 0 0]]
 [[1 2 2]
 [3 3 4]
 [0 0 0]]
[[[1 2 2]
  [3 3 4]
  [0 0 0]]]
[1 2 2 3 3 4 0 0 0]  # 拍扁了

(3)T

ndarray.T:矩阵转置

# 例如
import numpy as np
list1 = [[1, 2], [2, 3], [3, 4]]  # (3, 2)
np1 = np.array(list1)
print(np1.T)
# 终端显示
[[1 2 3]
 [2 3 4]]

(4)transpose

np.transpose(a, axes=None):通过改变轴号来改变形状,axes是轴号,如果不传,则功能跟T一样,表示转置

# 例如
import numpy as np
list1 = [[[1, 2], [2, 3], [3, 4]], [[3, 4], [2, 3], [1, 2]], [[3, 4], [2, 3], [1, 2]]]  # (3, 3, 2)
np1 = np.array(list1)
print(np1.shape)
print(np.transpose(np1).shape)  # 不传参数,等于转置
print(np.transpose(np1, (0, 2, 1)).shape)  # 原来的轴是(0,1,2),对应形状是(3,3,2),按照要求改变轴的顺序号,变成(0, 2, 1),0对应3,1对应3,2对应2,所以变成(3,2,3)
# 终端显示
(3, 3, 2)
(2, 3, 3)
(3, 2, 3)

(5)swapaxes

np.swapaxes(a, axis1, axis2):将数组a调换两个轴

# 例如
import numpy as np
list1 = [[[1, 2], [2, 3], [3, 4]], [[3, 4], [2, 3], [1, 2]], [[3, 4], [2, 3], [1, 2]]]  # (3, 3, 2)
np1 = np.array(list1)
print(np1.swapaxes(1, 2).shape)  # 调换1轴和2轴
# 终端显示
(3, 2, 3)

你可能感兴趣的:(转码,python,numpy,开发语言,改行学it,人工智能)