不看你一定后悔,基于 Numpy 的满满干货,你还在等什么呢?

和她纠纠缠缠这么久了,今天终于下了了断,花了一个多星期把这个份Numpy上分宝典准备好,你还在等什么呢?如果你想学数据分析,那我一定推荐你看我这份上分宝典,绝对全网最细,不服就看,带你学好,学会,学棒!
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

学习numpy的理由

比如我们用python的循环来计算下面的平均数计算的话

import time
import numpy as np

start = time.perf_counter()
x = np.random.random(10000000)
x_mean = sum(x) / len(x)
end = time.perf_counter() - start
print('一共耗时为:{:.4f}s'.format(end))
一共耗时为:1.3968s
start = time.perf_counter()
y = np.random.random(10000000)
y_mean = np.mean(y)
end = time.perf_counter() -start
print('一共耗时为:{:.4f}s'.format(end))
一共耗时为:0.1008s

当我们使用numpy库的mean方法求平均的时候 时间则大幅减少,这或许是我们学习numpy的理由之一,高效运算

求平均数函数

np.mean()

学习Numpy的方法

numpy的简单操作和简单属性

我们将一维数组称之为秩为 1 的数组。通常,N 维数组的秩为 N。因此,二维数组称为秩为 2 的数组。数组的另一个重要特性是形状。数组的形状是指每个维度的大小。例如,秩为 2 的数组的形状对应于数组的行数和列数。你将发现,NumPy ndarray 具有特殊的属性,使我们能够非常直观地获取关于 ndarray 的信息

%pdb  # 魔术方法---调试命令ss
x = np.array([[1, 2, 3, 4, 5],[6, 7, 8, 9, 10]])
print(x)  
print(x.dtype)  #  类型具有向上转型成浮点数 同时含有整形和浮点 则转化为浮点型
print(type(x))  # 类型: ndarray
print(x.shape)  # 根据维度来返回数组的形状 这里 2行 五列
print(x.size)  # 返回数组的大小
print(np.mean(x))  # 求数组的平均数
Incorrect argument. Use on/1, off/0, or nothing for a toggle.
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]]
int32
<class 'numpy.ndarray'>
(2, 5)
10
5.5

将python类型转换为ndarray类型 进行运算

print('np.array()这个是最基础的创建一个数组函数')
np.array()这个是最基础的创建一个数组函数

列表转换

a_list = [11, 12, 13, 14, 15]
ax = np.array(a_list)
print(f'a= {a_list}')
print('a的平均数为 =',np.mean(ax))

a= [11, 12, 13, 14, 15]
a的平均数为 = 13.0

字符串转换

y = np.array(['hello', 'world','are you ok'])
print(f'y = {y}')
print('形状元组 = ', y.shape) 
print(y.dtype)  # 10个unicode字符
y = ['hello' 'world' 'are you ok']
形状元组 =  (3,)
<U10

请务必注意,Python 列表和 ndarray 之间的最大区别是:与 Python 列表不同的是,ndarray 的所有元素都必须类型相同。因此,虽然我们可以同时使用整数和字符串创建 Python 列表,但是无法在 ndarray 中同时使用这两种类型。如果向 np.array() 函数提供同时具有整数和字符串的 Python 列表,NumPy 会将所有元素解析为字符串

z = np.array([123, 'hello'])
print(z.dtype)  # 这个时候就解析成了字符串
<U11

数组的保存和读取

x = np.arange(10).reshape((2, 5))
np.save('my_array', x)  # 保存到文件夹
x = np.load('my_array.npy')  # 数组的读取方式
print('x= \n', x)
x= 
 [[0 1 2 3 4]
 [5 6 7 8 9]]

使用numpy中内置函数生成数组

创建一个全0的数组

必要的时候我们也可以指定数组的类型,在这里我们改变y的类型,我们也可以使用reshape改变形状,我们来试试!

x = np.zeros((4,4))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
y = np.zeros((5,5), dtype=int)
print('y=\n{} shape = {} type = {}'.format(y, y.shape, y.dtype))
x = x.reshape((2,8))  # 在这里我们把x改成 2 * 8 的数组  但是一定要确保size一样大小,不然会报错
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))   
x=
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]] shape = (4, 4) type = float64
y=
[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]] shape = (5, 5) type = int32
x=
[[0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]] shape = (2, 8) type = float64

创建一个全为1的数组

x = np.ones((4, 4))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]] shape = (4, 4) type = float64

创建一个指定形状的数组

使用 np.full(shape, constant value) 函数有两个参数。第一个参数是你要创建的 ndarray 的形状,第二个参数是你要向数组中填充的常数值,那我们来试试

x = np.full((4, 4), 5)
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[5 5 5 5]
 [5 5 5 5]
 [5 5 5 5]
 [5 5 5 5]] shape = (4, 4) type = int32

如果你很细心的话,你会发现线性代数中的基本数组是单位矩阵。单位矩阵是主对角线上全是 1,其他位置全是 0 的方形矩阵。而函数 np.eye(N) 会创建一个对应于单位矩阵的方形 N x N ndarray。因为所有单位矩阵都是方形,因此,np.eye() 函数仅接受一个整数作为参数。我们来看一个示例:

创建单位数组

x = np.eye(4, dtype = int)  # 接受一个n值  函数会自动创建一个n * n 的单位矩阵  你也可以更改数组的类型
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[1 0 0 0]
 [0 1 0 0]
 [0 0 1 0]
 [0 0 0 1]] shape = (4, 4) type = int32

创建给定值对角矩阵

我们使用np.diag() 创建一个给定值的对角矩阵

x = np.diag([10, 20, 30, 40])
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[10  0  0  0]
 [ 0 20  0  0]
 [ 0  0 30  0]
 [ 0  0  0 40]] shape = (4, 4) type = int32

NumPy 还允许你创建在给定区间内值均匀分布的 ndarray。 np.arange(start,stop,step)左闭右开
NumPy 的np.arange() 函数非常强大,可以传入一个参数、两个参数或三个参数。下面将介绍每种情况,以及如何创建不同种类的 ndarray

创建整数数组

x = np.arange(10) # 当传入一个值的时候 表示 0-9 默认步长为1 的一维矩阵
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
y = np.arange(2,10)  # 当传入二个值的时候  2-9
print('y=\n{} shape = {} type = {}'.format(y, y.shape, y.dtype))
z = np.arange(2,10,2) # 当传入三个值的时候 2-9 步长为2
print('z=\n{} shape = {} type = {}'.format(z, z.shape, z.dtype))
x=
[0 1 2 3 4 5 6 7 8 9] shape = (10,) type = int32
y=
[2 3 4 5 6 7 8 9] shape = (8,) type = int32
z=
[2 4 6 8] shape = (4,) type = int32

但是这种情况是对于整数来说,虽然这个方法可以创建小数的数组,但是我们不建议这样做,精度很低,这里提供了一个新的函数np.linspace(start, stop, N)左闭右闭 N为表示等差分为多少份,我们来试试!

创建小数数组

x = np.linspace(1,10,5)
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[ 1.    3.25  5.5   7.75 10.  ] shape = (5,) type = float64

ps:加入关键词 endpoint = False 可以让这个方法不适用结尾的数

创建随机数组

我们也可以创建随机的数组np.random.randint([statr, stop), shape)

扩展:np.random.permutation(N) 函数会创建一个从 0 到 N - 1的随机排列的整数集

x = np.random.randint(1,5,(5,5))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
x=
[[4 3 2 4 1]
 [1 2 1 2 2]
 [4 4 1 3 4]
 [4 3 2 2 2]
 [3 3 2 4 1]] shape = (5, 5) type = int32

这里我们对应一下random模块中的randint 区别在于 random模块中的randint的区间范围是二边闭口

import random
x = [random.randint(1,3) for i in range(50)]
print(x)
[2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2, 1, 2, 3, 2, 3, 3, 3, 2, 3, 1, 2, 1, 3, 2, 2, 2, 1, 2, 3, 2, 2, 2, 1, 3, 1, 2, 2, 3, 3, 2, 1, 3, 3, 3, 2, 2, 2, 3]

创建特定数组

在某些情况下,你可能需要创建由满足特定统计学特性的随机数字组成的 ndarray。例如,你可能希望 ndarray 中的随机数字平均值为 0。NumPy 使你能够创建从各种概率分布中抽样的数字组成的随机 ndarray。例如,函数 np.random.normal(mean, standard deviation, size=shape) 会创建一个具有给定形状的 ndarray,其中包含从正态高斯分布(具有给定均值和标准差)中抽样的随机数字。我们来创建一个 1,000 x 1,000 ndarray,其中包含从正态分布(均值为 0,标准差为 0.1)中随机抽样的浮点数

x = np.random.normal(0, 0.1, size = (1000,1000))
print('x=\n{} shape = {} type = {}'.format(x, x.shape, x.dtype))
print(f'平均数 {np.mean(x)}')  # 平均数无线接近为0
print(f'max {np.max(x)}')
print(f'min {np.min(x)}')
x=
[[ 0.17472034  0.16466766  0.20174347 ...  0.0553319  -0.01653249
   0.03948098]
 [ 0.06888259  0.0134556  -0.01425262 ...  0.06732574 -0.05307537
   0.03314621]
 [-0.02105612 -0.12779988  0.18961712 ... -0.09320825 -0.0666076
  -0.05079914]
 ...
 [ 0.06068892  0.07034235 -0.01217326 ... -0.11759619 -0.00506101
  -0.06323254]
 [ 0.02748854 -0.012596   -0.07722798 ... -0.06668634  0.11173246
  -0.16214736]
 [ 0.08337674  0.13369851 -0.14506456 ...  0.16990955  0.09465047
   0.04350329]] shape = (1000, 1000) type = float64
平均数 -7.668087217691369e-05
max 0.5025681985823912
min -0.5569429250768674

数组的访问,删除,修改,增加, 插入和叠片

元素访问,赋值修改

若是一维数组,访问的方式和字符串一样,不做介绍,若是二维数组,访问存在二种方式,例如我下方的例子,可以x[0, 0]或者x[0][0] 看个人喜爱

ps: 索引值均从0开始计算

x = np.arange(1,11).reshape((2, 5))
print(x)
print(f'x[0, 0] = {x[0,0]}')
print(f'x[1, 1] = {x[1][1]}')
print(f'x[1, 3] = {x[1][3]}')
x[1,3] = 99  # 直接赋值修改
print(f'x[1, 3] = {x[1][3]}\n')
print(x)
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]]
x[0, 0] = 1
x[1, 1] = 7
x[1, 3] = 9
x[1, 3] = 99

[[ 1  2  3  4  5]
 [ 6  7  8 99 10]]

元素删除

np.delete(ndarray, elements, axis) 函数删除元素。此函数会沿着指定的轴从给定 ndarray 中删除给定的元素列表。对于秩为 1 的 ndarray,不需要使用关键字 axis。对于秩为 2 的 ndarray,axis = 0 表示选择行,axis = 1 表示选择列。我们来看一些示例

x = np.arange(0,10)  # 对于一维数组
print(f'before \n{x}')  
x = np.delete(x, [0,9])  
print(f'after \t\t删除第0个和第9个\n {x}')
print('-'*40)
y = np.arange(0,15).reshape((3,5)) # 对于二维数组
print(f'before \n {y}')
y_1 = np.delete(y, 0, axis = 0) 
print(f'after1 \t\t删除第0行 \n {y_1}')
y_2 = np.delete(y, [0,1], axis = 0)  
print(f'after2 \t\t删除第0和第1行\n {y_2}')
print('-'*40)
y_3 = np.delete(y, 0, axis = 1) 
print(f'after3 \t\t 删除第一列\n {y_3}')
y_4 = np.delete(y, [0,1], axis =1)
print(f'after4 \t\t 删除第一列和第二列\n {y_4}')
before 
[0 1 2 3 4 5 6 7 8 9]
after 		删除第0个和第9个
 [1 2 3 4 5 6 7 8]
----------------------------------------
before 
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
after1 		删除第0行 
 [[ 5  6  7  8  9]
 [10 11 12 13 14]]
after2 		删除第0和第1行
 [[10 11 12 13 14]]
----------------------------------------
after3 		 删除第一列
 [[ 1  2  3  4]
 [ 6  7  8  9]
 [11 12 13 14]]
after4 		 删除第一列和第二列
 [[ 2  3  4]
 [ 7  8  9]
 [12 13 14]]

元素增加

使用 np.append(ndarray, elements, axis) 函数向 ndarray 中附加值。该函数会将给定的元素列表沿着指定的轴附加到 ndarray 中
一维数组的增加就是往后叠,二维数组的增加还需要添加axis的值,和删除同理,0为行1为列,增加要考虑行和列是否对齐,简单来说,形状对齐,下面我们来试试一些例子

print('对于一维数组'.center(40,'-'))
x = np.arange(10)
print(f'before \t {x}')
x = np.append(x , 10)
print(f'after \t {x}')
print('对于二维数组'.center(40,'-'))
y = np.arange(0,15).reshape((3,5))
print(f'before=\n{y}')
y_1 = np.append(y, [[0, 1, 2, 4, 5]], axis = 0)
print(f'after=增加在最后一行\n{y_1}')
y_2 = np.append(y, [[0],[0],[0]], axis = 1)
print(f'after=增加在最后一列\n{y_2}')
-----------------对于一维数组-----------------
before 	 [0 1 2 3 4 5 6 7 8 9]
after 	 [ 0  1  2  3  4  5  6  7  8  9 10]
-----------------对于二维数组-----------------
before=
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
after=增加在最后一行
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [ 0  1  2  4  5]]
after=增加在最后一列
[[ 0  1  2  3  4  0]
 [ 5  6  7  8  9  0]
 [10 11 12 13 14  0]]

元素插入

使用 np.insert(ndarray, index, elements, axis) 函数向 ndarray 中插入值。此函数会将给定的元素列表沿着指定的轴插入到 ndarray 中,并放在给定的索引前面。我们来看一些例子把

print('对于一维数组'.center(40, '-'))
x = np.arange(10)
print(f'before=\n{x}')
x = np.insert(x, 1, [10])
print(f'after=我们在下标为1的位置插入10\n{x}')
print('对于二维数组'.center(40, '-'))
y = np.arange(15).reshape((3, 5))
print(f'before=\n{y}')
y_1 = np.insert(y, 1,[[5, 5, 5, 5, 5]], axis =0)
print(f'after_1=我们在第一行的位置插入五个五\n{y_1}')
y_2 = np.insert(y, 1, [[6]], axis = 1)
print(f'after_2=我们在第一列的位置插入三个6\n{y_2}')
-----------------对于一维数组-----------------
before=
[0 1 2 3 4 5 6 7 8 9]
after=我们在下标为1的位置插入10
[ 0 10  1  2  3  4  5  6  7  8  9]
-----------------对于二维数组-----------------
before=
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
after_1=我们在第一行的位置插入五个五
[[ 0  1  2  3  4]
 [ 5  5  5  5  5]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
after_2=我们在第一列的位置插入三个6
[[ 0  6  1  2  3  4]
 [ 5  6  6  7  8  9]
 [10  6 11 12 13 14]]

叠片操作

可以使用 np.vstack() 函数进行垂直堆叠,或使用 np.hstack() 函数进行水平堆叠。请务必注意,为了堆叠 ndarray,ndarray 的形状必须相符。我们来看一些例子

x = np.arange(4).reshape((2,2))
print(f'x=\n{x}')
y = np.array([4, 5])
print(f'y=\n{y}')
print('水平叠片'.center(40, '-'))
x_h = np.hstack((x, y.reshape(2, 1)))
print(f'y水平叠在x的后面\n{x_h}')
print('垂直叠片'.center(40, '-'))
x_v = np.vstack((x, y))
print(f'y垂直叠在x的下面\n{x_v}')
x=
[[0 1]
 [2 3]]
y=
[4 5]
------------------水平叠片------------------
y水平叠在x的后面
[[0 1 4]
 [2 3 5]]
------------------垂直叠片------------------
y垂直叠在x的下面
[[0 1]
 [2 3]
 [4 5]]

元素等切

np.hsplit(ndarray, n) # 将数组等分和竖着等切
np.vsplit(ndayyay, n) # 将数组等分和横着等切 
import numpy as np
x = np.arange(6).reshape((2,3))
print('x=\n',x)
x_1 = np.hsplit(x,3)
print(f'将x等分为三份,这里取第一段=\n',x_1[0])
x_2 =np.hsplit(x,(0,1))
print(f'在第0个位置前和第1个位置前竖着切=\n',x_2)
print('np.vsplit() 用法一样')
x=
 [[0 1 2]
 [3 4 5]]
将x等分为三份,这里取第一段=
 [[0]
 [3]]
在第0个位置前和第1个位置前竖着切=
 [array([], shape=(2, 0), dtype=int32), array([[0],
       [3]]), array([[1, 2],
       [4, 5]])]
np.vsplit() 用法一样

数组的切片操作

一维数组的切片

import numpy as np
print('一维数组的切片'.center(40, '-'))
x = np.arange(10)
print(f'before \n{x}')
print(f'after 切前三个元素 \n{x[:3]}')
----------------一维数组的切片-----------------
before 
[0 1 2 3 4 5 6 7 8 9]
after 切前三个元素 
[0 1 2]

二维数组的切片

二维数组的切片x[行:列] :切片的顺序都是按照先行 后列

print('二维数组的切片'.center(40, '-'))
x = np.arange(20).reshape((4, 5))
print(f'before \n{x}')
x_1 = x[:3,:3]
print(f'after 切前三行前三列的交叉元素 \n{x_1}')
x_2 = x[1:3,1:3]
print(f'after 切第二行第三行 和第二列第三列的交叉元素 \n{x_2}')
print('行赋空操作'.center(40,'-'))
x_3 = x[ : ,2]
x_4 = x[ : ,2:3]
print(f'after\t行赋空的话,则代表行全选,这里取第三列\n{x_3}\tshape={x_3.shape} \t 这就变成了一维数组')
print(f'after\t这种手法,切列的操作,和上面不一样\n{x_4}\t\tshape={x_4.shape}\t 这样就变成了二维数组')
print('列赋空操作'.center(40, '-'))
x_5 = x[1, : ]
print(f'after 列赋空,则取第二行\n{x_5}')
----------------二维数组的切片-----------------
before 
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
after 切前三行前三列的交叉元素 
[[ 0  1  2]
 [ 5  6  7]
 [10 11 12]]
after 切第二行第三行 和第二列第三列的交叉元素 
[[ 6  7]
 [11 12]]
-----------------行赋空操作------------------
after	行赋空的话,则代表行全选,这里取第三列
[ 2  7 12 17]	shape=(4,) 	 这就变成了一维数组
after	这种手法,切列的操作,和上面不一样
[[ 2]
 [ 7]
 [12]
 [17]]		shape=(4, 1)	 这样就变成了二维数组
-----------------列赋空操作------------------
after 列赋空,则取第二行
[5 6 7 8 9]

切片的修改操作

x = np.arange(20).reshape((4,5))
print(f'before\n{x}')
x_1 = x[:2, :2]
print(f'after 随便切点数据 \n {x_1}')
print('我们尝试对切好数据进行修改')
x_1[0,0] = 55
print(f'修改x_1[0,0] = 55 \nafter\n{x_1}')
print(f'此时x\n{x}')
before
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
after 随便切点数据 
 [[0 1]
 [5 6]]
我们尝试对切好数据进行修改
修改x_1[0,0] = 55 
after
[[55  1]
 [ 5  6]]
此时x
[[55  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]

这里我们就会发现对于x_1的修改操作,原数组x居然也会改变,这与我们之前理解的字符串切片貌似不一样啊,在这里我必须得强调,他们二个都是同一个
ndarray属性的不同名称而已,如果用c来讲,他们的地址是一样的,只不过指向了不同的地方,他只是创建了原数组的一个视图,所以我们修改后者,前者也会发生变化,那我们就不能修改了? 别急,python还提供了一个新的函数,**np.copy(ndarray)**这个函数会创建一个新的副本,那我们就可以修改了
下面给出例子

创建副本数组

x = np.arange(20).reshape((4,5))
x_1 = x[:3, :3].copy()
x_2 = np.copy(x[:3, :3])
print('代码上面给出了二种copy的方法')
print(f'x=\n{x}')
print(f'after随意切点=\n{x_1}')
x_1[0,0] = 555
print(f'after修改之后的x_1 =\n{x_1}')
print(f'afrer修改之后的x=\n{x}')
print('这样操作原数组就不会发生变化')
代码上面给出了二种copy的方法
x=
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
after随意切点=
[[ 0  1  2]
 [ 5  6  7]
 [10 11 12]]
after修改之后的x_1 =
[[555   1   2]
 [  5   6   7]
 [ 10  11  12]]
afrer修改之后的x=
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
这样操作原数组就不会发生变化

数组与数组之间相互切片

x = np.arange(20).reshape((4,5))
y = np.array([1,3])
print('x=\n',x)
print('y=',y)
print()
print('在x数组中使用y进行切片'.center(40, '-'))
print(f'after 行赋空切,这里切第2列和第四列=\n{x[ : ,y]}')
print(f'after 列赋空切, 这里切第2行和第四行=\n{x[y, : ]}')
x=
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
y= [1 3]

--------------在x数组中使用y进行切片--------------
after 行赋空切,这里切第2列和第四列=
[[ 1  3]
 [ 6  8]
 [11 13]
 [16 18]]
after 列赋空切, 这里切第2行和第四行=
[[ 5  6  7  8  9]
 [15 16 17 18 19]]

对角线切片

NumPy 还提供了从 ndarray 中选择特定元素的内置函数。例如,np.diag(ndarray, k=N) 函数会以 N 定义的对角线提取元素。默认情况下,k=0,表示主对角线。k > 0 的值用于选择在主对角线之上的对角线中的元素,k < 0 的值用于选择在主对角线之下的对角线中的元素。我们来看一个示例

x = np.arange(20).reshape((4,5))
print('x=\n',x)
print()
x_1 = np.diag(x)
print(f'切x的主对角线\t{x_1}\n')
x_2 = np.diag(x, k=1)
print(f'切x的主对角线上面的一对\t{x_2}\n')
x_3 = np.diag(x ,k=-1)
print(f'切x的主对角线下面的一对\t{x_3}\n')
x=
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]

切x的主对角线	[ 0  6 12 18]

切x的主对角线上面的一对	[ 1  7 13 19]

切x的主对角线下面的一对	[ 5 11 17]

切唯一元素

可以使用 np.unique() 函数查找 ndarray 中的唯一元素。np.unique(ndarray) 函数会返回给定 ndarray 中的 唯一元素(去重后的元素)看一个例子

x = np.random.randint(0,3,(4,5)) # 这里使用random随机数组
print('x=\n',x)
print(f'x中的唯一元素为:  {np.unique(x)}')
x=
 [[0 2 0 1 2]
 [0 0 2 0 2]
 [1 0 2 2 2]
 [0 2 1 2 2]]
x中的唯一元素为:  [0 1 2]

数组的布尔型索引,集合运算和排序

可能有人要问,我们之前不是学过数组的访问和切片,那为啥还要学这个,我们想一想,前者我们是有确定值或者确定位置,那如果我们没有确定的消息
呢,一切都是未知的,我们需要按照一个范围来获得我们需要的元素,那么布尔型索引这个就可以完成我们的任务,下面看一个例子

数组的布尔型索引

x = np.arange(25).reshape((5,5))
print('x=\n',x)
print(f'查找大于14的数 = \n {x[x>14]}')
print(f'查找小于等于5的数 = \n {x[x<=5]}')
print(f'查找大于10小于20的数 =\n {x[(x>10) & (x<20)]}')
x=
 [[ 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]]
查找大于14的数 = 
 [15 16 17 18 19 20 21 22 23 24]
查找小于等于5的数 = 
 [0 1 2 3 4 5]
查找大于10小于20的数 =
 [11 12 13 14 15 16 17 18 19]

ps:索引里面的判断式 不仅仅是我给出的这么的简单判断,还可以扩展很多表达式,可以自行探索探索

数组的集合运算

np.intersect1d()  交集
np.setdiff1d()    差集
np.union1d()      全集
注意这个1d 是数字1 不是字母l 这个我破梗我抗了这么多下终于发现
x = np.random.randint(1, 8, (3,3))
print('x=\n',x)
y = np.random.randint(2, 10,(3,3))
print('y=\n',y)

print(f'x和y的交集元素=\n {np.intersect1d(x,y)}')
print(f'x和y的差集元素=\n {np.setdiff1d(x,y)}')
print(f'x和y的全集元素=\n {np.union1d(x,y)}')
x=
 [[5 1 7]
 [7 6 1]
 [1 2 2]]
y=
 [[2 3 7]
 [7 3 7]
 [5 6 8]]
x和y的交集元素=
 [2 5 6 7]
x和y的差集元素=
 [1]
x和y的全集元素=
 [1 2 3 5 6 7 8]

数组的排序

x = np.random.randint(1,10,(10,))
print('x=\n',x)
print('第一种排序方式 x = \n',np.sort(x))
print('after x = \n', x)
print('第二种排序方式 x = ')
x.sort()
print(x)
print('after x =\n',x)
x=
 [4 9 3 8 8 8 4 7 5 1]
第一种排序方式 x = 
 [1 3 4 4 5 7 8 8 8 9]
after x = 
 [4 9 3 8 8 8 4 7 5 1]
第二种排序方式 x = 
[1 3 4 4 5 7 8 8 8 9]
after x =
 [1 3 4 4 5 7 8 8 8 9]

ps:当使用sort当作函数来使用,我们不会改变原数组x,当我们使用sort当作方式来使用,我们会改变原数组x,而且sort()中也可以加入axis参数,同样0为行1为列去判断排序的行还是列

x = np.random.randint(1,16,(5,3))
print('x=\n',x)
print()
print(f'对行排序 =\n {np.sort(x, axis = 0)}\n')

print(f'对列排序 = \n {np.sort(x , axis = 1)}\n')

print('行和列的选择取决于axis的值,仍然是0为行,1为列')
x=
 [[14  5 11]
 [ 9 15 15]
 [ 3 12  8]
 [ 5  5  4]
 [ 4 10  7]]

对行排序 =
 [[ 3  5  4]
 [ 4  5  7]
 [ 5 10  8]
 [ 9 12 11]
 [14 15 15]]

对列排序 = 
 [[ 5 11 14]
 [ 9 15 15]
 [ 3  8 12]
 [ 4  5  5]
 [ 4  7 10]]

行和列的选择取决于axis的值,仍然是0为行,1为列

数组的排序加强版

我们也可以对排序后的值去重操作,在上面我们使用了切唯一值函数np.unique() 这里也可以使用

x = np.array([1,2,1,4,2,6,3,8])
print('x=',x)
print(f'排序并去重 =  {np.sort(np.unique(x))}')
x= [1 2 1 4 2 6 3 8]
排序并去重 =  [1 2 3 4 6 8]

数组的算数运算和广播操作

算数运算

相加 x+y   或者np.add()
相减 x-y   或者np.subtract()
相乘 x*y   或者np.multiply(x,y)
相除 x/y   或者np.divide(x,y)
print('一维数组的操作'.center(40,'-'))
x = np.arange(5)
y = np.arange(5,10)
print('x=',x)
print('y=',y)
print(f'相加使用x+y = {x+y}')
print(f'相加使用add = {np.add(x,y)}')
----------------一维数组的操作-----------------
x= [0 1 2 3 4]
y= [5 6 7 8 9]
相加使用x+y = [ 5  7  9 11 13]
相加使用add = [ 5  7  9 11 13]
print('二维数组的操作'.center(40,'-'))
x = np.arange(10).reshape((2,5))
y = np.arange(10,20).reshape((2,5))
print('x=\n',x)
print('y=\n',y)
print(f'相乘使用x*y = {x * y}')
print(f'相乘使用multiply = {np.multiply(x,y)}')
----------------二维数组的操作-----------------
x=
 [[0 1 2 3 4]
 [5 6 7 8 9]]
y=
 [[10 11 12 13 14]
 [15 16 17 18 19]]
相乘使用x*y = [[  0  11  24  39  56]
 [ 75  96 119 144 171]]
相乘使用multiply = [[  0  11  24  39  56]
 [ 75  96 119 144 171]]

数学函数

! 这里重要提一个函数 np.mean()求平均数 里面参数一个对象ndarray还有一个axis这二个很重要

! 当axis = 0 的时候,压缩行,求每列的均值

! 当axis = 1 的时候,压缩列,求每行的均值

怎么理解呢,你就把这个数组当成一个千层饼一样,行压缩就是垂直把这个千层饼压扁,从上面看数量上不就和列个数相同。
列压缩,就水平的把千层饼压扁,从左右看数量上不就等于行的个数了

x = np.arange(5)
print('x=',x)
print(f'幂运算exp = {np.exp(x)}')
print(f'开根号运算 sqrt = {np.sqrt(x)}')
print(f'平方运算 power = {np.power(x,2)}')
print(f'平均数 mean = {np.mean(x)}')
print(f'最大数 max = {np.max(x)}')
print(f'最小数 min = {np.min(x)}')
print(f'总数sum = {np.sum(x)}')
print(f'标准差 std = {np.std(x)}')
print(f'中位数 median = {np.median(x)}')
print('对于二维数组来说,只要在里面增加参数axis 同样行为0列为1')
x= [0 1 2 3 4]
幂运算exp = [ 1.          2.71828183  7.3890561  20.08553692 54.59815003]
开根号运算 sqrt = [0.         1.         1.41421356 1.73205081 2.        ]
平方运算 power = [ 0  1  4  9 16]
平均数 mean = 2.0
最大数 max = 4
最小数 min = 0
总数sum = 10
标准差 std = 1.4142135623730951
中位数 median = 2.0
对于二维数组来说,只要在里面增加参数axis 同样行为0列为1

广播操作

x = np.arange(10).reshape((2,5))
print('x=\n',x)
print()
print(f'x+2 =\n {x+2}')
print()
print(f'x*2 =\n{x*2}')

x=
 [[0 1 2 3 4]
 [5 6 7 8 9]]

x+2 =
 [[ 2  3  4  5  6]
 [ 7  8  9 10 11]]

x*2 =
[[ 0  2  4  6  8]
 [10 12 14 16 18]]

在这里numpy将数字2进行了广播操作,意思就是把他的形状和要进行操作的数组进行了同化,这样就能简单的进行数组的变化,下面拿出特殊的例子来看看

x = np.arange(3)
y = np.arange(9).reshape((3,3))
z = np.arange(9,12).reshape((3,1))
print('x=',x)
print()
print('y=\n',y)
print()
print('z=\n',z)
print()
print(f'x+y =\n  {x+y}')
print()
print(f'y+z =\n  {y+z}')
x= [0 1 2]

y=
 [[0 1 2]
 [3 4 5]
 [6 7 8]]

z=
 [[ 9]
 [10]
 [11]]

x+y =
  [[ 0  2  4]
 [ 3  5  7]
 [ 6  8 10]]

y+z =
  [[ 9 10 11]
 [13 14 15]
 [17 18 19]]

这里虽然二个数组的形状不一样,但是我们也可以进行操作,也是运用了广播操作,对于x+y numpy把x同化y,对于y+z numpy把z同化y,这样就可以进行操作,总之就是把较小数组同化成为较大数组。

后记:我认为学习是一个持久的事情,学习一个函数库也是一样,不可能我们一下子能记住这么多函数,看了这么多python官网文献,我也只是记得经常用的,但是没有什么能阻拦我们学习的心,兄弟们,干他就完事了,趁现在还年轻,能学,那就不要放弃,若干年后,你会感谢今天的付出,你也会感谢你看过的这篇文章,我也会感谢你为我点的赞和关注,这是我坚持下去的一个动力,非常感谢。
正所谓 长风破浪会有时,直挂直挂云帆济沧海!

发布了11 篇原创文章 · 获赞 191 · 访问量 9495

猜你喜欢

转载自blog.csdn.net/qq_45906219/article/details/105130435