numpy-常用函数总结
目录- numpy-常用函数总结
学习地址:https://blog.csdn.net/zkx990121/article/details/119136515
1. Axis理解
1.1 Axis维度
简单来说,最外面的括号代表着axis=0,依次往里的括号对应的axis的计数就依次加1
操作方式:如果指定轴进行相关的操作,那么会使用轴下的每一个直接子元素的第0个,第1个,第2个…分别进行相关的操作示例:
x = np.array([[0,1],[2,3]])
print(x)
# [[0 1]
# [2 3]]
1.求 x 数组在axis = 0 和 axis=1 两种情况下的和
# 求列和
x.sum(axis=0)
print("x.sum(axis=0):", x.sum(axis=0))
# x.sum(axis=0): [2 4]
# 求行和
x.sum(axis=1)
print("x.sum(axis=1):", x.sum(axis=1))
# x.sum(axis=1): [1 5]
2.用np.max求 axis=0 和 axis=1 两种情况下的最大值
np.random.seed(100)
x = np.random.randint(1,10,size=(3,5))
print("np.random.randint(1,10,size=(3,5)) x: \n", x)
# np.random.randint(1,10,size=(3,5)) x:
# [[9 9 4 8 8]
# [1 5 3 6 3]
# [3 3 2 1 9]]
x.max(axis=0)
print("x.max(axis=0): \n", x.max(axis=0))
# x.max(axis=0):
# [9 9 4 8 9]
x.max(axis=1)
print("x.max(axis=1): \n", x.max(axis=1))
# x.max(axis=1):
# [9 6 9]
3.用 np.delete 在 axis=0 和 axis=1 两种情况下删除元素
np.random.seed(100)
x = np.random.randint(1,10,size=(3,5))
print("np.random.randint(1,10,size=(3,5)): \n", x)
# np.random.randint(1,10,size=(3,5)) x:
# [[9 9 4 8 8]
# [1 5 3 6 3]
# [3 3 2 1 9]]
#删除第0行
np.delete(x,0,axis=0)
print("np.delete(x,0,axis=0): \n", np.delete(x,0,axis=0))
# np.delete(x,0,axis=0):
# [[1 5 3 6 3]
# [3 3 2 1 9]]
#删除第0列
np.delete(x,0,axis=1)
print("np.delete(x,0,axis=1): \n", np.delete(x,0,axis=1))
# np.delete(x,0,axis=1):
# [[9 4 8 8]
# [5 3 6 3]
# [3 2 1 9]]
1.2 三维及多维数组
#生成一个三维数组
y = np.arange(24).reshape(2,2,6)
print("生成一个三维数组 np.arange(24).reshape(2,2,6): \n", y)
# [[[ 0 1 2 3 4 5]
# [ 6 7 8 9 10 11]]
# [[12 13 14 15 16 17]
# [18 19 20 21 22 23]]]
#取最大值
y.max(axis=0)
print("y.max(axis=2): \n", y.max(axis=2))
# [[ 5 11]
# [17 23]]
1.3 总结
- 最外面的括号代表着 axis=0,依次往里的括号对应的 axis 的计数就依次加1
- 如果指定轴进行相关的操作,那么他会使用轴下面的每个子元素的第0个,第1个,第2个...分别进行相关的操作
- np.delete是直接删除指定轴下的第几个直接子元素
2. 创建数组
2.1 使用np.array创建
q = np.array([1, 2, 3, 4])
print(q)
# [1 2 3 4]
print(type(q))
# <class 'numpy.ndarray'>
2.2 使用np.arange创建
#创建0-10步数为2的数组 结果为[0,2,4,6,8]
b = np.arange(0, 10, 2)
print(b)
# [0 2 4 6 8]
2.3 np.random.random
#3. np.random.random创建一个N行N列的数组
# 其中里面的值是0-1之间的随机数
# 创建3行3列的数组
c = np.random.random((3, 3))
print(c)
# [[ 0.28709175 0.0133334 0.9399995 ]
# [ 0.81712176 0.43983614 0.69228111]
# [ 0.75798902 0.2459419 0.84720639]]
2.4 np.random.randint
#4. np.random.randint创建一个N行N列的数组
# 其中值的范围可以通过前面2个参数来指定
# 创建值的范围为[0,9)的5行5列数组
d = np.random.randint(0, 10, size=(5, 5))
print(d)
# [[4 5 6 9 1]
# [8 0 4 0 7]
# [3 8 3 9 6]
# [2 9 4 4 9]
# [3 1 9 9 1]]
2.5 特殊函数
2.5.1 np.zeros
## N行N列的全零数组
### 例如:3行3列全零数组
array_zeors = np.zeros((3, 3))
print(array_zeors)
# [[ 0. 0. 0.]
# [ 0. 0. 0.]
# [ 0. 0. 0.]]
2.5.2 np.ones
## N行N列的全一数组
### 例如:5行5列全一数组
array_ones = np.ones((5, 5))
print(array_ones)
# [[ 1. 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.5.3 np.full
## 全部为指定值的N行N列数组
### 例如:值为0的2行3列数组
array_full = np.full((3, 4), 3)
print(array_full)
# [[3 3 3 3]
# [3 3 3 3]
# [3 3 3 3]]
2.5.4 np.eye
## 生成一个在斜方形上元素为1,其他元素都为0的N行N列矩阵
### 例如:6行6列矩阵
array_eye = np.eye(6)
print(array_eye)
# [[ 1. 0. 0. 0. 0. 0.]
# [ 0. 1. 0. 0. 0. 0.]
# [ 0. 0. 1. 0. 0. 0.]
# [ 0. 0. 0. 1. 0. 0.]
# [ 0. 0. 0. 0. 1. 0.]
# [ 0. 0. 0. 0. 0. 1.]]
2.6. 注意
- 数组中的数据类型必须一致,要么全部为整型,要么全部为浮点类型,要么全部为字符串类型
- 不能同时出现多种数据类型
3. random模块
3.1 np.random.seed
用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed()值,则每次生成的随机数都相同,
如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异不同。一般没有特殊要求不用设置。
3.2 np.random.rand
生成一个值为 [0,1) 之间的数组,形状由参数指定,如果没有参数,那么将返回一个随机值
#产生随机数
np.random.rand()
print("np.random.rand(): \n", np.random.rand())
# 0.0923385947687978
#产生随机数组 两行三列
np.random.rand(2,3)
print("np.random.rand(2,3): \n", np.random.rand(2,3))
# [[0.20445225 0.87811744 0.02738759]
# [0.67046751 0.4173048 0.55868983]]
3.3 np.random.randn
生成均值(μ)为0,标准差(σ)为1的标准正态分布的值
#生成一个2行3列的数组,数组中的值都满足标准正态分布
data12 = np.random.randn(2,3)
print("np.random.randn(2,3): \n", data12)
# [[-0.3224172 -0.38405435 1.13376944]
# [-1.09989127 -0.17242821 -0.87785842]]
3.4 np.random.randint
生成指定范围内的随机数,并且可以通过size参数指定维度
#生成值在0-10之间,3行5列的数组
data12_1 = np.random.randint(10,size=(3,5))
print("生成值在0-10之间,3行5列的数组: \n", data12_1)
# [[5 1 9 3 4]
# [8 1 4 0 3]
# [9 2 0 4 9]]
#生成值在1-20之间,3行6列的数组
data12_2 = np.random.randint(1,20,size=(3,6))
print("生成值在1-20之间,3行6列的数组: \n", data12_2)
# [[16 3 8 9 10 4]
# [ 8 5 6 7 9 1]
# [ 3 11 16 16 8 11]]
3.5 np.random.choice
从一个列表或者数组中,随机进行采样。或者是从指定的区间中进行采样,采样个数可以通过参数
#从数组中随机选择三个值
data12_3 = np.random.choice(data12.flatten(), 3)
print("从数组中随机选择三个值: \n", data12_3)
# [-0.3224172 -0.3224172 -0.38405435]
#从数组中获取值组成新的数组
data12_4 = np.random.choice(data12.flatten(),size=(3,4))
print("从数组中获取值组成新的数组: \n", data12_4)
# [[-0.38405435 -0.87785842 -1.09989127 -0.3224172 ]
# [-0.3224172 -0.87785842 -0.87785842 -0.17242821]
# [-0.87785842 1.13376944 -0.17242821 -1.09989127]]
#从指定值随机取值 (示例:从0-10之间随机取3个值)
data12_5 = np.random.choice(10,3)
print("从指定值随机取值 (示例:从0-10之间随机取3个值): \n", data12_5)
# [4 4 7]
3.6 np.random.shuffle
把原来数组的元素的位置打乱
q12 = np.arange(10)
print("np.arange(10): \n", q12)
# [0 1 2 3 4 5 6 7 8 9]
#将数组q12的元素的位置都会进行随机更换
#shuffle没有返回值,直接打乱原数组位置
np.random.shuffle(q12)
print("shuffle没有返回值,直接打乱原数组位置: \n", q12)
# [6 2 3 0 1 8 5 7 9 4]
4. 数组数据类型
4.1 数据类型
数据类型 | 描述 | 唯一标识符 |
---|---|---|
bool | 用一个字节存储的布尔类型(True或False) | b |
int8 | 一个字节大小,-128 至 127 | i1 |
int16 | 整数,16 位整数(-32768 ~ 32767) | i2 |
int32 | 整数,32 位整数(-2147483648 ~ 2147483647) | i4 |
int64 | 整数,64 位整数(-9223372036854775808 ~ 9223372036854775807) | i8 |
uint8 | 无符号整数,0 至 255 | u1 |
uint16 | 无符号整数,0 至 65535 | u2 |
uint32 | 无符号整数,0 至 2 ** 32 - 1 | u4 |
uint64 | 无符号整数,0 至 2 ** 64 - 1 | u8 |
float16 | 半精度浮点数:16位,正负号1位,指数5位,精度10位 | f2 |
float32 | 单精度浮点数:32位,正负号1位,指数8位,精度23位 | f4 |
float64 | 单精度浮点数:64位,正负号1位,指数11位,精度52位 | f8 |
complex64 | 复数,分别用两个32位浮点数表示实部和虚部 | c8 |
complex128 | 复数,分别用两个64位浮点数表示实部和虚部 | c16 |
object_ | python对象 | O |
string_ | 字符串 | S |
unicode_ | unicode类型 | U |
4.2 创建数组指定类型
# i1 是int8
q2 = np.array([1, 2, 3, 4, 5], dtype='i1')
print(q2) # [1 2 3 4 5]
q21 = np.array([1, 2, 3, 4, 5], dtype=int)
print(q21) # [1 2 3 4 5]
4.3 查询数据类型
y = np.arange(24).reshape(2,2,6)
print(y.dtype) # int32
4.4 修改数据类型
c2 = np.array([1, 2, 3], dtype='i2')
print(c2.dtype) # int16
d2 = c2.astype('f2')
print(d2) # [ 1. 2. 3.]
print(d2.dtype) # float16
4.5 总结
- Numpy是基于C语言编写,引用了C语言的数据类型,所以Numpy的数组中数据类型多样
- 不同的数据类型有利于处理海量数据,针对不同数据赋予不同数据类型,从而节省内存空间
5. 多维数组
5.1 数组维度查询
# 打印维度
a3 = np.array([1, 2, 3])
print(a3.ndim)
# 1
a32 = np.array([
[5, 6, 7],
[22, 33, 55]
])
print(a32.ndim)
# 2
q33 = np.array([
[
[33, 44, 55],
[66, 77, 88]
],
[
[2, 1, 3],
[1, 2, 1]
]
])
print(q33.ndim) # 3
5.2 数组形状查询
print(q33.shape)
# (2, 2, 3)
# 打印行列
q34 = np.array([0, 1, 22])
print(q34.shape) # (3,)
q35 = np.array([[0, 1, 22], [2, 1, 3]])
print(q35.shape) # (2, 3)
5.3 修改数组形状
# 以 q33为例
print(q33)
# [[[33 44 55]
# [66 77 88]]
#
# [[ 2 1 3]
# [ 1 2 1]]]
print(q33.shape) # (2, 2, 3)
q33_1 = q33.reshape(3, 4)
print(q33_1)
# [[33 44 55 66]
# [77 88 2 1]
# [ 3 1 2 1]]
print(q33_1.shape) # (3, 4)
# 扁平化 (多维数组转化为一维数组)
q33_2 = q33.flatten()
print(q33_2) # [33 44 55 66 77 88 2 1 3 1 2 1]
print(q33.ndim) # 3
5.4 元素个数和内存
# 数组元素个数
count = q33.size
print(count) # 12
# 各元素所占内存
print(q33.itemsize) # 4
# 各元素类型
print(q33.dtype) # int32
# 数组所占内存
print(q33.itemsize * q33.size) # 48
5.5 总结
-
一般情况下,数组维度最大到三维,一般会把三维以上的数组转化为二维数组来计算
-
ndarray.ndim 查询数组的维度
-
ndarray.shape 可以看到数组的形状(几行几列),shape是一个元组,里面有几个元素代表是几维数组
-
ndarray.reshape 可以修改数组的形状。条件只有一个,就是修改后的形状的元素个数必须和原来的个数一致。
reshape 不会修改原来数组的形状,只会将修改后的结果返回。
-
ndarray.size 查询数组元素个数
-
ndarray.itemsize 可以看到数组中每个元素所占内存的大小,单位是字节。(1个字节=8位)
6. 数组索引和切片
6.1 一维数组
# 6.1 一维数组
q41 = np.arange(10)
print("q41: ", q41) # q41: [0 1 2 3 4 5 6 7 8 9]
print("q41[5]: " , q41[5]) # q41[5]: 5
print("q41[-1]: " , q41[-1]) # q41[-1]: 9
# 6.2 切片
print("切片: q41[2:5]: ", q41[2:5]) # [2 3 4]
# 6.3 使用步长
print("使用步长 q41[::3]: ", q41[::3]) # [0 3 6 9]
6.2 二维数组
通过中括号来索引和切片,在中括号中使用逗号进行分割.
逗号前面的是行,逗号后面的是列,如果多维数组中只有一个值,那么这个值就是行
q42 = np.random.randint(0,10, size=(4,6))
print("二维数组: \n", q42)
# [[4 8 6 6 0 3]
# [8 3 6 8 3 0]
# [5 6 7 1 8 0]
# [9 0 5 3 0 8]]
#获取第0行数据
print("获取第0行数据: ", q42[0]) # 1
#获取第1,2行数据
print("获取第1,2行数据: ", q42[1:3])
# [[6 0 9 4 1 2]
# [4 1 4 6 8 1]]
#获取多行数据 例0,2,3行数据
print("获取多行数据 例0,2,3行数据: ", q42[[0,2,3]])
# [[9 0 7 9 4 1]
# [4 1 4 6 8 1]
# [1 5 0 9 9 4]]
#获取第二行第一列数据
print("获取第二行第一列数据: ", q42[2,1]) # 1
#获取多个数据 例:第一行第四列、第二行第五列数据
print("获取多个数据 例:第一行第四列、第二行第五列数据: ", q42[[1,2],[4,5]])
# [1 1]
#获取多个数据 例:第一、二行的第四、五列的数据
print("获取多个数据 例:第一、二行的第四、五列的数据: ", q42[1:3,4:6])
# [[1 2]
# [8 1]]
#获取某一列数据 例:第一列的全部数据
print("获取某一列数据 例:第一列的全部数据: ", q42[:,1])
# [0 0 1 5]
#获取多列数据 例:第一、三列的全部数据
print("获取多列数据 例:第一、三列的全部数据: ", q42[:,[1,3]])
# [[0 9]
# [0 4]
# [1 6]
# [5 9]]
6.3 总结
- 如果数组是一维的,那么索引和切片就是和python的列表是一样的
- 如果是多维的(这里以二维为例),那么在中括号中,给两个值,两个值是通过逗号分隔的,逗号前面的是行,逗号后面的是列。如果中括号中只有一个值,那么就是代表行。
- 如果是多维数组(以二维为例),那么行的部分和列的部分,都是遵循一维数组的方式,可以使用整型、切片,还可以使用中括号的形式代表不连续的。比如a[[1,2],[3,4]],那么返回的就是第一行第三列、第二行第四列的两个值。
7. 布尔索引
# 1 生成1-24的4行6列的二维数组
q5 = np.arange(24).reshape((4,6))
# 2 获取比10小的元素
print("获取比10小的元素: \n", q5[q5<10])
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 3 获取小于5或大于10的元素
ret = q5[(q5<5) | (q5>10)]
print("获取小于5或大于10的元素: ", ret)
# array([ 0, 1, 2, 3, 4, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,23])
7.1总结
- 布尔索引是通过相同数据上的 True 还是 False 来进行提取的。
- 提取条件可以为一个或多个,当提取条件为多个时使用
&
代表且,使用 | 代表或 - 当提取条件为多个时,每个条件要使用圆括号括起来
8. 数组元素值的替换
8.1 方式一:索引
利用索引可以做值的替换,把满足条件的位置的值替换成其他值
#创建数组元素值为[0,10)随机数的3行5列数组
q6 = np.random.randint(0,10,size=(3,5))
print("创建数组元素值为[0,10)随机数的3行5列数组: \n", q6)
# [[4 1 7 6 9]
# [7 2 4 2 9]
# [2 4 0 7 4]]
#将q6数组第2行数据全部更换为33
q6[1] = 33
print("将q6数组第一行数据全部更换为0: \n", q6)
#将q6数组第2行数据更换为[1,2,3,4,5] -- 数据个数要对应
q6[1] = np.array([1,2,3,4,5])
print("将q6数组第2行数据更换为[1,2,3,4,5]: \n", q6)
8.2 方式二:条件索引
#数组中值小于3的元素全部替换为1
q6[q6 < 3] = 1
print("数组中值小于3的元素全部替换为1: \n", q6)
# [[7 8 8 6 1]
# [1 1 3 4 5]
# [9 3 4 8 4]]
8.3 方式三:函数
#将q6数组中小于5的值替换为2,剩余值替换为3
result = np.where(q6<5, 2, 3)
print("将q6数组中小于5的值替换为2,剩余值替换为3: \n", result)
# [[2 3 2 2 3]
# [2 2 2 2 3]
# [2 3 2 2 2]]
8.4 总结
- 使用索引或者切片来替换值
- 使用条件索引来替换值
- 使用where函数来实现替换值
9. 数组的广播机制
9.0. 数组的广播原则
如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的。广播会在全是和(或)长度为1的维度上进行。
9.1 数组与数字运算
#生成3行5列 值为0-5随机整数的数组
q7 = np.random.randint(0,5,size=(3,5))
print("生成3行5列 值为0-5随机整数的数组: \n", q7)
# [[0 2 1 1 0]
# [0 1 4 4 2]
# [4 0 3 2 3]]
#数组中的所有元素都乘2
print("数组中的所有元素都乘2: \n", q7*2)
# [[0 4 2 2 0]
# [0 2 8 8 4]
# [8 0 6 4 6]]
#数组中所有的元素只保留2位小数
print("数组中所有的元素只保留2位小数: \n", q7.round(2))
# [[0 2 1 1 0]
# [0 1 4 4 2]
# [4 0 3 2 3]]
9.2 数组与数组运算
- 数组形状一致时 各个元素相加减(满足数组广播机制)
# q7
# [[3 2 2 3 4]
# [1 3 3 1 2]
# [3 4 1 0 2]]
q72 = np.random.randint(0,5,size=(3,5))
print("3*5 [0,5)数组: \n", q72)
# [[0 2 0 4 0]
# [0 4 0 3 1]
# [2 3 2 2 2]]
print("q7 + q72: \n", q7 + q72)
# [[3 4 2 7 4]
# [1 7 3 4 3]
# [5 7 3 2 4]]
- 形状不一致的数组不能相加减(不满足数组广播机制)
q72 = np.random.randint(0,5,size=(3,4))
# print("q7 + q72 形状不一致: \n", q7 + q72)
# q7 + q72 报错 : ValueError: operands could not be broadcast together with shapes (3,5) (3,4)
- 两个数组行数相同 ,其中一个数组列数为1(满足数组广播机制)
q73 = np.random.randint(0,5,size=(3,1))
# q7
# [[0 1 3 1 1]
# [4 4 0 4 2]
# [1 3 2 2 2]]
print("q73: \n", q73)
# [[2]
# [4]
# [2]]
print("q7 size: {}, q73 size: {}".format(q7.shape, q73.shape))
# q7 size: (3, 5), q73 size: (3, 1)
print("q7+q73: \n", q7+q73)
# [[2 3 5 3 3]
# [8 8 4 8 6]
# [3 5 4 4 4]]
- 两个数组列数相同 ,其中一个数组行数为1(满足数组广播机制)
q74 = np.random.randint(0,5,size=(1,5))
# q7
# [[0 1 3 1 1]
# [4 4 0 4 2]
# [1 3 2 2 2]]
print("q74: \n", q74)
# [[2 4 1 1 1]]
print("q7 size: {}, q74 size: {}".format(q7.shape, q74.shape))
# q7 size: (3, 5), q74 size: (1, 5)
print("q7+q74: \n", q7+q74)
# [[2 5 4 2 2]
# [6 8 1 5 3]
# [3 7 3 3 3]]
9.3总结
- 数组和数字直接进行运算是没有问题的
- 两个 shape 想要的数组是可以进行运算的
- 如果两个 shape 不同的数组,想要进行运算,那么需要看他们是否满足广播原则
10. 数组形状的操作
10.1 数组形状的改变
10.1.1 reshape 与 resize
reshape 与 resize 都是用来修改数组形状的,但是存在不同:
- reshape 是将数组转换成指定的形状,然后返回转换后的结果,对于原数组的形状是不会发生改变的
- resize 是将数组转换成指定的形状,会直接修改数组本身,并且不会返回任何值
q81 = np.random.randint(0,10,size=(3,4))
print("q81: \n", q81)
# reshape是将数组转换成指定的形状,然后返回转换后的结果,对于原数组的形状是不会发生改变的
q82 = q81.reshape((2,6))
print("q81: \n", q81)
# [[2 9 2 7]
# [9 1 6 9]
# [0 5 7 3]]
print("q82: \n", q82)
# [[2 9 2 7 9 1]
# [6 9 0 5 7 3]]
# resize是将数组转换成指定的形状,会直接修改数组本身,并且不会返回任何值
q82 = q81.resize((4,3))
print("q81: \n", q81)
# [[2 9 2]
# [7 9 1]
# [6 9 0]
# [5 7 3]]
print("q82: \n", q82)
# None
10.1.2 flatten 与 ravel
faltten 与 ravel 都是将多维数组转换为一维数组,但是存在不同:
- flatten 是将数组转换为一维数组后,然后将这个拷贝返回回去,然后后续对这个返回值进行修改不会影响之前的数组
- ravel 是将数组转换为一维数组后,将视图(引用)返回回去,后续对这个返回值进行修改会影响之前的数组
q83 = np.random.randint(0,10,size=(3,4))
print("q83: \n", q83)
# [[6 3 9 4]
# [8 1 3 7]
# [2 2 5 4]]
# flatten是将数组转换为一维数组后,然后将这个拷贝返回回去,然后后续对这个返回值进行修改不会影响之前的数组
q84 = q83.flatten()
print("q84: \n", q84)
# [6 3 9 4 8 1 3 7 2 2 5 4]
q84[0] = 100
print("q83[0,0]: \n", q83[0,0])
# 结果为:6
print("q84[0]: \n", q84[0])
# 结果为:100
# ravel是将数组转换为一维数组后,将这个视图(引用)返回回去,后续对这个返回值进行修改会影响之前的数组
q85 = q83.ravel()
q85[0] = 100
print("q85[0]: \n", q85[0])
# 结果为:100
print(q83[0,0])
print("q83[0,0]: \n", q83[0,0])
# 结果为:100
10.2 数组的叠加
vstack代表在垂直方向叠加,如果想要叠加成功,那么列数必须一致 hstack代表在水平方向叠加,如果想要叠加成功,那么行数必须一致 concatenate 可以手动的指定axis参数具体在哪个方向叠加:
- 如果axis=0,代表在水平方向叠加
- 如果axis=1,代表在垂直方向叠加
- 如果axis=None,会先进行叠加,再转化为1维数组
vstack1 = np.random.randint(0,10,size=(3,4))
print("vstack1: \n", vstack1)
# [[0 7 6 4]
# [2 6 9 3]
# [9 9 1 4]]
vstack2 = np.random.randint(0,10,size=(2,4))
print("vstack2: \n", vstack2)
# [[3 2 6 1]
# [8 3 7 2]]
#垂直方向叠加的两种方式
vstack3 = np.vstack([vstack1,vstack2])
print("vstack3: \n", vstack3)
# [[0 7 6 4]
# [2 6 9 3]
# [9 9 1 4]
# [3 2 6 1]
# [8 3 7 2]]
vstack4 = np.concatenate([vstack1,vstack2],axis=0)
print("vstack4: \n", vstack4)
# [[0 7 6 4]
# [2 6 9 3]
# [9 9 1 4]
# [3 2 6 1]
# [8 3 7 2]]
h1 = np.random.randint(0,10,size=(3,4))
print("h1: \n", h1)
# [[6 7 2 7]
# [4 3 1 4]
# [2 1 7 9]]
h2 = np.random.randint(0,10,size=(3,1))
print("h2: \n", h2)
# [[9]
# [4]
# [5]]
#水平方向叠加的两种方式
h3 = np.hstack([h2,h1])
print("h3: \n", h3)
# [[9 6 7 2 7]
# [4 4 3 1 4]
# [5 2 1 7 9]]
h4 = np.concatenate([h2,h1],axis=1)
print("h4: \n", h4)
# [[9 6 7 2 7]
# [4 4 3 1 4]
# [5 2 1 7 9]]
# [9 4 5 6 7 2 7 4 3 1 4 2 1 7 9]
#先识别垂直叠加或水平叠加 后转换为一维数组
h5 = np.concatenate([h2,h1],axis=None)
print(h5)
print("h5: \n", h5)
# [9 4 5 6 7 2 7 4 3 1 4 2 1 7 9]
10.3 数组的切割
hsplit 代表在水平方向切割,按列进行切割。
hsplit 切割方式两种:
第1种直接指定平均切割成多少列,
第2种是指定切割的下标值
vsplit 代表在垂直方向切割,按行进行切割。切割方式与 hsplit 相同
split/array_split 是手动的指定 axis 参数,axis=0 代表按行进行切割,axis=1代表按列进行切割
hs1 = np.random.randint(0,10,size=(3,4))
print("hs1: \n", hs1)
# [[8 6 5 3]
# [2 6 4 9]
# [3 8 2 6]]
#水平方向平均分为2份 (要求列数可被此数整除)
np.hsplit(hs1,2)
print("np.hsplit(hs1,2): \n", np.hsplit(hs1,2))
# [array([[8, 6],
# [2, 6],
# [3, 8]]),
# array([[5, 3],
# [4, 9],
# [2, 6]])]
#水平方向分为1,1,2列(在下标为1,2处切割)
np.hsplit(hs1,(1,2))
print("np.hsplit(hs1,(1,2)): \n", np.hsplit(hs1,(1,2)))
# [array([[8],
# [2],
# [3]]),
# array([[6],
# [6],
# [8]]),
# array([[5, 3],
# [4, 9],
# [2, 6]])]
vs1 = np.random.randint(0,10,size=(4,5))
print("vs1: \n", vs1)
# [[3 4 6 3 1]
# [7 9 2 9 6]
# [8 0 2 8 0]
# [5 9 3 2 3]]
#垂直方向平均分为4份
print("np.vsplit(vs1,4): \n", np.vsplit(vs1,4))
# [array([[3, 4, 6, 3, 1]]),
# array([[7, 9, 2, 9, 6]]),
# array([[8, 0, 2, 8, 0]]),
# array([[5, 9, 3, 2, 3]])]
#垂直方向分为1,2,1
print("np.vsplit(vs1,(1,3)): \n", np.vsplit(vs1,(1, 3)))
# [array([[3, 4, 6, 3, 1]]),
# array([[7, 9, 2, 9, 6],
# [8, 0, 2, 8, 0]]),
# array([[5, 9, 3, 2, 3]])]
#split/array_split(array,indicate_or_section,axis):用于指定切割方式,在切割的时候需要指定按照行还是列,axis=1代表按照列,axis=0代表按照行
#按列平均切割
print("np.split(hs1,4,axis=1): \n", np.split(hs1,4,axis=1))
# [array([[8],
# [2],
# [3]]),
# array([[6],
# [6],
# [8]]),
# array([[5],
# [4],
# [2]]),
# array([[3],
# [9],
# [6]])]
#按行平均切割
np.split(vs1,4,axis=0)
print("np.split(vs1,4,axis=0): \n", np.split(vs1,4,axis=0))
# [array([[3, 4, 6, 3, 1]]), array([[7, 9, 2, 9, 6]]), array([[8, 0, 2, 8, 0]]), array([[5, 9, 3, 2, 3]])]
10.4 矩阵转置
ndarray.T 转置
t1 = np.random.randint(0,10,size=(3,4))
print("t1: \n", t1)
# [[4 5 6 4]
# [2 5 4 5]
# [6 1 0 0]]
#数组t1转置
t1.T
print("t1.T 转置: \n", t1.T)
# [[4 2 6]
# [5 5 1]
# [6 4 0]
# [4 5 0]]
#矩阵相乘
t1.dot(t1.T)
print("t矩阵相乘 t1.dot(t1.T): \n", t1.dot(t1.T))
# [[93 77 29]
# [77 70 17]
# [29 17 37]]
ndarray.transpose() 转置
#transpose返回的是一个View,所以对返回值上进行修改会影响到原来的数组。
t2 = t1.transpose()
print("transpose()转置: \n", t2)
# [[4 2 6]
# [5 5 1]
# [6 4 0]
# [4 5 0]]
10.5 总结
-
数据的形状改变
(1)reshape和resize 都是重新定义形状的,但是 reshape 不会修改数组本身,而是将修改后的结果返回回去,而 resize 是直接修改数组本身的
(2) flatten 和 ravel 都是用来将数组变成一维数组的,并且他们都不会对原数组造成修改,但是 flatten 返回的是一个拷贝,所以对 flatten 的返回值的修改不会影响到原来数组,而 ravel 返回的是一个 View,那么对返回值的修改会影响到原来数组的值
-
数据的叠加
(1) concatenate 可以手动指定 axis 参数具体在哪个方向叠加 (建议使用)
-
数组的切割
(1) split/array_split 是手动的指定 axis 参数,axis=0 代表按行进行切割, axis=1 代表按列进行切割
-
矩阵转置
(1)可以通过 ndarray.T 的形式进行转置
11. View或者浅拷贝
11.1 不拷贝
只是简单的赋值,那么就不会进行拷贝
q9 = np.arange(12)
#这种情况不会进行拷贝
resq9 = q9
#返回True,说明b和a是相同的
print("resq9 is q9: ", resq9 is q9)
# resq9 is q9: True
11.2 浅拷贝
有些情况,会进行变量的拷贝,但是他们所指向的内存空间都是一样的,那么这种情况叫做浅拷贝,或者叫做View(视图)
q92 = q9.view()
print("q92 is q9: ", q92 is q9)
# q92 is q9: False
#返回false,说明q92与q9在栈区空间不同,但是所指向的内存空间是一样的
#对q92的值修改 同时也会对a进行修改
q92[0] = 100
print("q92: \n", q92)
# [100 1 2 3 4 5 6 7 8 9 10 11]
print("q9: \n", q9)
# [100 1 2 3 4 5 6 7 8 9 10 11]
11.3 深拷贝
将之前数据完完整整的拷贝一份放到另外一块内存空间中,这样就是两个完全不同的值了
q93 = q9.copy()
print(q93 is q9)
#返回False 说明在不同栈区
#数组d值被修改,数组a值不会被修改 说明内存空间不同
q93[1]=200
print("q9: \n", q9)
print("q93: \n", q93)
# q9:
# [100 1 2 3 4 5 6 7 8 9 10 11]
# q93:
# [100 200 2 3 4 5 6 7 8 9 10 11]
11.4 总结
在数组操作中分成3种拷贝:
- 不拷贝:直接赋值,那么栈区没有拷贝,只是用同一个栈区定义了不同的名称
- 浅拷贝:只拷贝栈区,栈区指定的堆区并没有拷贝
- 深拷贝:栈区和堆区都拷贝
12. 文件操作
12.1 操作CSV文件
12.1.1 文件保存
np.savetxt(frame,array,fmt="%.18e",delimiter=None)
函数功能:将数组保存到文件中参数说明:
- frame:文件、字符串或产生器,可以是.gz或.bz2的压缩文件
- array:存入文件的数组
- fmt:写入文件的格式,例如:%d %.2f %.18e
- delimter:分割字符串,默认是空格
scores = np.random.randint(0,100,size=(10,2))
print("scores: \n", scores)
# [[73 97]
# [39 23]
# [43 21]
# [22 96]
# [44 3]
# [88 63]
# [59 19]
# [37 90]
# [ 8 98]
# [90 46]]
#保存csv文件
np.savetxt("score.csv",scores,fmt="%d",delimiter=",",header="英语,数学",comments="")
# 英语,数学
# 73,97
# 39,23
# 43,21
# 22,96
# 44,3
# 88,63
# 59,19
# 37,90
# 8,98
# 90,46
12.1.2 读取文件
np.loadtxt(frame,dtype=np.float,delimiter=None,unpack=False)
函数功能:将数组保存到文件中参数说明:
- frame:文件、字符串或产生器,可以是.gz或.bz2的压缩文件
- dtype:数据类型,可选
- delimiter:分割字符串,默认是任何空格
- skiprows:跳过前面x行
- usecols:读取指定的列,用元组组合
- unpack:如果True,读取出来的数组是转置后的
#读取csv文件 跳过第一行的表头
b = np.loadtxt("score.csv",dtype=np.int,delimiter=",",skiprows=1)
print("load txt b: \n", b)
# [[73 97]
# [39 23]
# [43 21]
# [22 96]
# [44 3]
# [88 63]
# [59 19]
# [37 90]
# [ 8 98]
# [90 46]]
12.2 总结
-
np.savetxt 和 np.loadtxt 一般用来操作 CSV 文件,可以设置 header,但是不能存储3维以上的数组。
-
np.save 和 np.load 一般用来存储非文本类型的文件,不可以设置 header,但是可以存储3维以上的数组
13. NAN和INF值处理
13.1 介绍
NAN:Not A number,不是一个数字的意思,但是是浮点类型的,所以想要进行数据操作的时候需要注意他的类型
data = np.random.randint(0,10,size=(3,5))
data = data.astype(np.float)
print("data: \n", data)
#将数组中某个位置的值设置为NAN
data[0,1]=np.NAN
data[2,2]=np.NAN
print("data NAN: \n", data)
# [[ 9. nan 5. 0. 1.]
# [ 2. 4. 7. 0. 1.]
# [ 3. 1. nan 2. 0.]]
INF:Infinity,代表的是无穷大的意思,也是属于浮点类型。
np.inf 表示正无穷大,-np.inf 表示负无穷大,一般在出现除数为0的时候为无穷大。比如2/0
13.2 NAN特点
- NAN 和 NAN 不相等。比如
np.NAN != np.NAN
这个条件是成立的 - NAN 和任何值做运算,结果都是NAN
print("data[0,1] == data[2,2]: \n", data[0,1] == data[2,2])
# Result: False
13.3 处理缺失值
13.3.1 删除缺失值
有时候,我们想要将数组中的NAN删掉,那么我们可以换一种思路,就是只提取不为*NAN*的值
- 删除所有NAN的值
因为删除了值后数组将不知道该怎么变化,所以会被变成一维数组
data[~np.isnan(data)]
print("exact not NAN: \n", data[~np.isnan(data)])
# [9. 5. 0. 1. 2. 4. 7. 0. 1. 3. 1. 2. 0.]
- 查找NAN所在行
lines = np.where(np.isnan(data))[0]
print("NAN lines: \n", lines)
# [0 2]
使用delete方法删除指定的行,lines表示删除的行号,axis=0表示删除行
np.delete(data,lines,axis=0)
print("after delete NAN lines data: \n", data )
# [[ 6. nan 5. 7. 5.]
# [ 6. 2. 2. 3. 8.]
# [ 1. 1. nan 5. 6.]]
print("after delete NAN lines: \n", np.delete(data,lines, axis=0))
# [[6. 2. 2. 3. 8.]]
13.3.2 用其他值进行替代
data = np.random.randint(0,10,size=(3,5))
data = data.astype(np.float64)
print("data: \n", data)
#将数组中某个位置的值设置为NAN
data[0,1]=np.NAN
data[2,2]=np.NAN
print("data NAN: \n", data)
# [[ 4. nan 1. 6. 9.]
# [ 3. 4. 0. 9. 4.]
# [ 0. 1. nan 3. 6.]]
data[np.isnan(data)]=0
print("将NAN替换为0 : \n", data)
# [[4. 0. 1. 6. 9.]
# [3. 4. 0. 9. 4.]
# [0. 1. 0. 3. 6.]]
13.4 总结
- NAN:Not A Number的简写,不是一个数字,但是是属于浮点类型
- INF:无穷大,在除数为0的情况下会出现INF
- NAN和所有的值进行计算结果都是等于NAN
NAN != NAN
- 可以通过np.isnan来判断某个值是不是NAN
- 处理值的时候,可以通过删除NAN的形式进行处理,也可以通过值的替换进行处理
- np.delete比较特殊,通过axis=0来代表行,而其他大部分函数通过axis=1来代表行
Reference
https://blog.csdn.net/zkx990121/article/details/119136515
标签:总结,函数,random,print,数组,np,array,numpy,axis From: https://www.cnblogs.com/tian777/p/17618349.html