首页 > 其他分享 >numpy-常用函数总结

numpy-常用函数总结

时间:2023-08-09 22:58:00浏览次数:30  
标签:总结 函数 random print 数组 np array numpy axis

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.deleteaxis=0axis=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 总结

  1. 最外面的括号代表着 axis=0,依次往里的括号对应的 axis 的计数就依次加1
  2. 如果指定轴进行相关的操作,那么他会使用轴下面的每个子元素的第0个,第1个,第2个...分别进行相关的操作
  3. 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. 注意

  1. 数组中的数据类型必须一致,要么全部为整型,要么全部为浮点类型,要么全部为字符串类型
  2. 不能同时出现多种数据类型

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 总结

  1. Numpy是基于C语言编写,引用了C语言的数据类型,所以Numpy的数组中数据类型多样
  2. 不同的数据类型有利于处理海量数据,针对不同数据赋予不同数据类型,从而节省内存空间

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 总结

  1. 一般情况下,数组维度最大到三维,一般会把三维以上的数组转化为二维数组来计算

  2. ndarray.ndim 查询数组的维度

  3. ndarray.shape 可以看到数组的形状(几行几列),shape是一个元组,里面有几个元素代表是几维数组

  4. ndarray.reshape 可以修改数组的形状。条件只有一个,就是修改后的形状的元素个数必须和原来的个数一致。

    reshape 不会修改原来数组的形状,只会将修改后的结果返回。

  5. ndarray.size 查询数组元素个数

  6. 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 总结

  1. 如果数组是一维的,那么索引和切片就是和python的列表是一样的
  2. 如果是多维的(这里以二维为例),那么在中括号中,给两个值,两个值是通过逗号分隔的,逗号前面的是行,逗号后面的是列。如果中括号中只有一个值,那么就是代表行。
  3. 如果是多维数组(以二维为例),那么行的部分和列的部分,都是遵循一维数组的方式,可以使用整型、切片,还可以使用中括号的形式代表不连续的。比如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总结

  1. 布尔索引是通过相同数据上的 True 还是 False 来进行提取的。
  2. 提取条件可以为一个或多个,当提取条件为多个时使用&代表且,使用 | 代表或
  3. 当提取条件为多个时,每个条件要使用圆括号括起来

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 总结

  1. 使用索引或者切片来替换值
  2. 使用条件索引来替换值
  3. 使用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 数组与数组运算

  1. 数组形状一致时 各个元素相加减(满足数组广播机制)
# 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]]
  1. 形状不一致的数组不能相加减(不满足数组广播机制)
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. 两个数组行数相同 ,其中一个数组列数为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. 两个数组列数相同 ,其中一个数组行数为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总结

  1. 数组和数字直接进行运算是没有问题的
  2. 两个 shape 想要的数组是可以进行运算的
  3. 如果两个 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. 数据的形状改变

    (1)reshape和resize 都是重新定义形状的,但是 reshape 不会修改数组本身,而是将修改后的结果返回回去,而 resize 是直接修改数组本身的

    (2) flatten 和 ravel 都是用来将数组变成一维数组的,并且他们都不会对原数组造成修改,但是 flatten 返回的是一个拷贝,所以对 flatten 的返回值的修改不会影响到原来数组,而 ravel 返回的是一个 View,那么对返回值的修改会影响到原来数组的值

  2. 数据的叠加

    (1) concatenate 可以手动指定 axis 参数具体在哪个方向叠加 (建议使用)

  3. 数组的切割

    (1) split/array_split 是手动的指定 axis 参数,axis=0 代表按行进行切割, axis=1 代表按列进行切割

  4. 矩阵转置

    (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种拷贝:

  1. 不拷贝:直接赋值,那么栈区没有拷贝,只是用同一个栈区定义了不同的名称
  2. 浅拷贝:只拷贝栈区,栈区指定的堆区并没有拷贝
  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 总结

  1. np.savetxt 和 np.loadtxt 一般用来操作 CSV 文件,可以设置 header,但是不能存储3维以上的数组。

  2. 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特点

  1. NAN 和 NAN 不相等。比如 np.NAN != np.NAN 这个条件是成立的
  2. 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*的值

  1. 删除所有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.]
  1. 查找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 总结

  1. NAN:Not A Number的简写,不是一个数字,但是是属于浮点类型
  2. INF:无穷大,在除数为0的情况下会出现INF
  3. NAN和所有的值进行计算结果都是等于NAN
  4. NAN != NAN
  5. 可以通过np.isnan来判断某个值是不是NAN
  6. 处理值的时候,可以通过删除NAN的形式进行处理,也可以通过值的替换进行处理
  7. 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

相关文章

  • 每日总结8月9日
    今天亲戚家电脑坏了,我爷爷奶奶不太懂我的专业,就让我去修电脑,我说我不是学这个的啊,他们说不就是摆弄电脑吗都一样,外行看热闹,内行看门道,我们大学生看别的系的学生跟资深程序员看我们并无太大差别,努力提升自己的实力,才能看出门道完成任务......
  • Python基础知识总结
     前言     本总结所观看视频如下:变量,数字,字符串,注释_哔哩哔哩_bilibili【Python】3小时不挂_哔哩哔哩_bilibili目录前言一、基本命令 二、基本计算语句 三、字符串操作 四、官方文档的使用五、列表与元组 六、字典 七、集合 八、值类型变量与引用类型变量 九、pr......
  • 【机器学习|数学基础】Mathematics for Machine Learning系列之矩阵理论(20):方阵函数
    前言Hello!小伙伴!非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ 自我介绍ଘ(੭ˊᵕˋ)੭昵称:海轰标签:程序猿|C++选手|学生简介:因C语言结识编程,随后转入计算机专业,有幸拿过一些国奖、省奖…已保研。目前正在学习C++/Linux/Python学习经验:扎实基础+多做笔记+多......
  • 【总结一下|LaTex语法】一些常用的LaTex语法小知识
    文章目录快速检索矩阵语法示例上标下标求和分数希腊字母语法示例大括号算式标签字母头上横线字母头上加^号字母头上加波浪线字母头上加点输入中括号大于等于小于等于...字母上添加波浪线向量积分符号举例波浪线整数、实数、自然数子集、真子集、空集箭头空格、缩进加粗绝对值上括......
  • 【总结一下|PTA】浙大版《Python 程序设计》题目集
    前言Hello!小伙伴!非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ 自我介绍ଘ(੭ˊᵕˋ)੭昵称:海轰标签:程序猿|C++选手|学生简介:因C语言结识编程,随后转入计算机专业,有幸拿过一些国奖、省奖…已保研。目前正在学习C++/Linux/Python学习经验:扎实基础+多做笔记+多......
  • 农村高中生源转型期提升学生二次函数建模能力的课堂探究
         建模思想是一种核心的数学思想,学习的根本目的是使高中生灵活地利用建模思想去对实际的问题进行求解。而在数学课堂教学中渗透建模思想期间,必须要首先精心选择一些恰当的数学内容,具体需要结合学生自身的数学学情以及数学知识认知和接受能力等来选择一些恰当的数学教......
  • MySQL 之【视图】【触发器】【存储过程】【函数】【事物】【数据库锁】【数据库备份】
    一.多表联合查询 创建表和数据#多表查询语法select字段1,字段2...from表1,表2...[where条件]注意:如果不加条件直接进行查询,则会出现以下效果,这种结果我们称之为 笛卡尔乘积#查询人员和部门所有信息select*fromperson,dept笛卡尔乘积公式:A表中数据条数  *......
  • 无涯教程-Perl - getprotoent函数
    描述此函数返回有效协议列表中的下一个条目:($name,$aliases,$protocol_number)语法以下是此函数的简单语法-getprotoent返回值此函数针对错误返回undef,否则返回标量context中的协议编号,并在列表context中返回错误协议记录的空列表(名称,别名,协议编号)。例以下是显......
  • Go语言——函数与闭包
    1函数定义在Go语言中定义函数使用func关键字,格式如下func函数名(参数)(返回值){ 函数体}函数名:由字母、数字、下划线组成。但首字母不能为数字,同一个包下,函数名称也不能重复参数:名称和类型组成,多个参数之间使用,分隔返回值:由返回值名称和返回值类型组成,返回值名称可以......
  • Python | 函数、数据容器
    1.函数函数:是组织好的,可重复使用的,用来实现特定功能的代码段。1.1简单案例重复使用计算字符串的长度str1="heystar"str2="python"str3="abcd"count=0for_instr1:count+=1print(f"字符串{str1}的长度是:{count}")count=0for_instr2:coun......