python编程 Numpy库的基础使用

目录

一:Numpy简介

二:ndarray的创建

三:ndarray的属性

四:切片 索引

五:数组的轴(二维数组)

六:二维数组 切片索引

七:高级索引

八:Numpy广播

九:ufunc函数 算术运算

十:ufunc函数 比较运算

十一:Numpy函数库 随机数

十二:Numpy函数库 求和、平均值、方差

十三:Numpy函数库 大小与排序


一:Numpy简介

NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,

支持大量的维度数组与矩阵运算,

此外也针对数组运算提供大量的数学函数库

NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:

一个强大的N维数组对象 ndarray(矩阵)

广播功能函数

整合 C/C++/Fortran 代码的工具

线性代数、傅里叶变换、随机数生成等功能

ndarray对象,主要学习包括有:

ndarray的创建

ndarray的属性

ndarray的索引与切片

多维数组

二:ndarray的创建

Numpy中的核心对象是ndarray

ndarray可以看成数组,类似于R语言的向量或者矩阵

Numpy里面所有函数都是围绕ndarry展开

示例1,如下

python 通过使用list创建 array

import numpy as np

# 通过python list创建 array
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
c = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])

print("a打印结果为:{}".format(a), type(a))
print("b打印结果为:{}".format(b), type(b))
print("c打印结果为:{}".format(c), type(c))

输出结果为:   a,b是一维;c是多维(二维)

c的0轴为[1 2 3 4]长度为4

c的1轴为[1 2 3 4]  [5 6 7 8]  ,长度为2

a打印结果为:[1 2 3 4] <class 'numpy.ndarray'>
b打印结果为:[5 6 7 8] <class 'numpy.ndarray'>
c打印结果为:[[1 2 3 4]
 [5 6 7 8]] <class 'numpy.ndarray'>

示例1 小结

ndarray对维数没有限制

[]从内到外分别是第0轴,第1轴,第2轴

c第0轴长度为4,第1轴长度为2

 示例2,如下

Numpy提供了专门用于生成ndarray的函数,提高创建ndarray的速度 

2.1 通过arange方法产生数组

0至1为区间,0.1为步幅

import numpy as np

# 通过arange方法产生数组
a = np.arange(0, 1, 0.1)  # start=0 end=1 step=0.1(间隔)
print(a)

输出结果:

[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]

2.2 创建等差数列  linspace

区间2至3 ,共5个数的等差

import numpy as np

# 创建等差数列
b = np.linspace(2.0, 3.0, num=5)
print(b)

输出结果:

[2.   2.25 2.5  2.75 3.  ]

2.3 二维数组   array

([[1, 2, 3, 4], [5, 6, 7, 8]])

import numpy as np

# 二维数组
c = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(c)

输出结果:

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

2.4 二维全0矩阵  zeros

[2,3]:2维3列 全0       [2--第1轴;3--第0轴]

import numpy as np

# 二维全0矩阵
e = np.zeros([2, 3])
print(e)

输出结果:

[[0. 0. 0.]
 [0. 0. 0.]] 

一维全0矩阵,示例

产生1维,长度为3的全0

0.  浮点数;一般用于分类算法,挑选出可能性最高的值的下标

import numpy as np

# 二维全0矩阵
d = np.zeros([3])
print(d)

输出结果:

[0. 0. 0.] 

示例3,常见矩阵创建

empty 空矩阵,只分配内存, np.int创建整数矩阵

zeros  0填充

ones   1填充

eye   对角线是1

3.1 ones使用

import numpy as np

# 二维全1矩阵
d = np.ones((2, 3), np.int)
print(d)

输出结果:

[[1 1 1]
 [1 1 1]]

import numpy as np

# 二维全1矩阵
d = np.ones((2, 3))
print(d)

 输出结果:若不写np.int,则输出1.(默认是float类型)

[[1. 1. 1.]
 [1. 1. 1.]]

示例4,自定义函数产生ndarray 

%4是0至3,+1后是1至4,最终结果如下

import numpy as np


def func(i):
    return i % 4 + 1


res = np.fromfunction(func, (10,))
print(res, type(res))

输出结果:

[1. 2. 3. 4. 1. 2. 3. 4. 1. 2.] <class 'numpy.ndarray'> 

注:fromfunction第一个参数接收计算函数,第二个参数接收数组的形状

三:ndarray的属性

ndarray的元素具有相同的元素类型dtype,规定元素的类型

常用的有int(整型),float(浮点型),complex(复数型)

示例1,如下

dtype,规定元素的类型 float

import numpy as np

a = np.array([1, 2, 3, 4], dtype=float)
print(a)

输出结果: a输出为

[1. 2. 3. 4.]

ndarray的shape属性用来获得它的形状也可以自己指定

示例2,如下 

shape       获得形状

reshape   维度变换  (相邻两个组成对应形状)

import numpy as np

c = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [7, 8, 9, 10]])
print(c.shape)

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(a.reshape((4, 2)))  # 维度变换

输出结果:shape和reshape分别为

(3, 4)
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

import numpy as np
import cv2

img_mat = cv2.imread("dog.jpg")
print(img_mat.shape)
# 行数 列数 通道数
# 341  499   3
# 高度 宽度  深度

 输出结果:图片通过shape操作

(341, 499, 3)

示例3

size元素个数、ndim 数组维度、 itemsize属性每个元素的大小,以字节为单位

3.1 size 元素个数

import numpy as np

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(a.size)

输出结果:8 

3.2  ndim数组维度

import numpy as np

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(a.ndim)

输出结果:2 

3.3 itemsize属性每个元素的大小,以字节为单位

如下 1 2 3 4,int为4字节

import numpy as np

c = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [7, 8, 9, 10]])
print(c.itemsize)

输出结果:4 

四:切片 索引

Numpy数组的切片索引,不会复制内部数组数据,

仅创建原始数据的新视图,以引用方式访问数据(同一块内存空间

切片索引的要点:

1 切片索引适用于有规律的查找指定位置的元素(元素位置位于等差序列);
2 当切片的数量少于数组维度时,缺失的维度索引被认为是一个完整切片,
省略与使用“:”或“…”等价;        

示例1,一维数组的切片索引

1.1,ndarray对象的内容可以通过索引或切片来访问和修改,和list是一样的

import numpy as np

a = np.arange(10)
print(a)

输出结果:

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

1.2,  为1.1的拓展  和list是一样的   start stop step

import numpy as np

a = np.arange(10)
print(a)

a[::-1]  # 逆序 [9,8,7,6,5,4,3,2,1,0]
print(a[::-1])
a[5]  # 5
print(a[5])
a[3:5]  # [3,4]
print(a[3:5])
a[:5]  # 从索引0开始取5个元素 [0,1,2,3,4]
print(a[:5])
a[:-1]  # 从最后一个索引开始向前取所有的元素[0,1,2,3,4,5,6,7,8]
print(a[:-1])
a[1:-1:2]  # 从索引1开始到最后一个结束,每2个取一个[1,3,5,7]
print(a[::-1])
a[5:1:-2]  # [5,3]
print(a[5:1:-2])
a[...]  # 索引全部元素,与a[:]等价
print(a[...])

输出结果:

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

1.3,可以通过切片的对ndarray中的元素进行更改

import numpy as np

a = np.arange(10)
a[2:4] = 100, 101
print(a)

输出结果: a[2:4] ,2和3的地方赋值修改为100,101

[  0   1 100 101   4   5   6   7   8   9] 

1.4, ndarray通过切片产生一个新的数组b,b和a共享同一块数据存储空间 

import numpy as np

# 输出1
a = np.array([0, 1, 100, 101, 4, 5, 6, 7, 8, 9])
b = a[3:7]
print(b)
# 输出2
b[2] = -10
print(b)
# 输出3
print(a)

输出结果:b和a共享同一块数据存储空间 ,原先的a被改变了

 [101   4   5   6]
[101   4 -10   6]
[  0   1 100 101   4 -10   6   7   8   9]

1.5,如果想改变这种情况,我们可以用整数数组索引法对数组元素切片,(不同地址操作)

整数数组索引  101 101 7 8
               b = a[[3, 3, -3, 8]]  

整数数组索引法,产生新数组,不会对原来的产生影响

import numpy as np

# 输出1
a = np.array([0, 1, 100, 101, 4, 5, 6, 7, 8, 9])
# 整数数组索引  101 101 7 8
b = a[[3, 3, -3, 8]]
print(b)
# 输出2
b[2] = 100
print(b)
# 输出3
print(a)
# [0 1 100 101 4 -10 6 7 8 9]

输出结果:

[101 101   7   8]
[101 101 100   8]
[  0   1 100 101   4   5   6   7   8   9]     原先的a最终没有被修改,即不同内存地址空间

五:数组的轴(二维数组)

二维数组有2个轴,轴索引分别是0和1 ,如下左图所示

示例1,数组转置

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
print(a[1][2], a[1, 2])
b = a.T  # 数组转置
print(b)

输出结果: 输出a[1][2]为6 ;a[1,2]为6    转置.T

6 6
[[1 4]
 [2 5]
 [3 6]] 

六:二维数组 切片索引

多维数组同样适用上述索引提取方法

示例1,如下 ,从第一行开始 行索引

import numpy as np

a = np.array([[1, 2, 3], [3, 4, 5], [4, 5, 6]])
print(a)

print(a[1:])

输出结果: a 与 a[1:]分别为

[[1 2 3]
 [3 4 5]
 [4 5 6]]
[[3 4 5]
 [4 5 6]] 

import numpy as np
import cv2

img_mat = cv2.imread("dog.jpg")
print(img_mat.shape)
# 行数 列数 通道数
# 341  499   3
# 高度 宽度  深度
print(img_mat[0], img_mat[0].shape)

 输出结果: 图片示例 img_mat.shape与img_mat[0].shape比较

(341, 499, 3)
[[233 221 203]
 [232 220 202]
 [232 220 202]
 ...
 [240 233 213]
 [240 233 213]
 [240 233 213]] (499, 3)

切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同

如果在行位置使用省略号,它将返回包含行中元素的 ndarray

示例2,如下 

import numpy as np

a = np.array([[1, 2, 3], [3, 4, 5], [4, 5, 6]])
print(a[..., 1])  # 第2列元素 所有行全选,取中间的一列
print(a[1, ...])  # 第2行元素 所有列全选,取中间的一行
print(a[..., 1:])  # 第2列及剩下的所有元素,第2列开始

输出结果, 3个结果分别为:

[2 4 5]
[3 4 5]
[[2 3]
 [4 5]
 [5 6]] 

七:高级索引

NumPy 比一般的 Python 序列提供更多的索引方式

除了用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引创立原数组的副本

7.1 整数数组索引

示例1,如下

获取数组中(0,0),(1,1)和(2,0)位置处的元素

import numpy as np

x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0, 1, 2], [0, 1, 0]]
print(y)  # 获取数组中(0,0),(1,1)和(2,0)位置处的元素

输出结果:获取数组中(0,0),(1,1)和(2,0)位置处的元素

[1 4 5] 

示例2,获取数组中 对应位置处的元素  如下

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = a[1:3, 1:3]
c = a[1:3, [1, 2]]
d = a[..., 1:]
print(b)  # [[5 6], [8,9]]
print(c)  # [[5 6], [8,9]]
print(d)  # [[1 2], [5 6], [8,9]]

输出结果:

[[5 6]
 [8 9]]
[[5 6]
 [8 9]]
[[2 3]
 [5 6]
 [8 9]] 

7.2 布尔索引 

布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组 

示例1,打印出大于5的元素,如下

import numpy as np

x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
# 现在我们会打印出大于 5 的元素  
b = x[x > 5]
print('大于5的元素是\n{}'.format(b))

输出结果:

大于5的元素是
[ 6  7  8  9 10 11] 

示例2,取补运算符,过滤 NaN(不确定值)[找到NaN并全部清除],如下

import numpy as np

# 使用了 ~(取补运算符)来过滤 NaN。
a = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
print(a[~np.isnan(a)])

输出结果:找到NaN(不确定值)并全部清除

[1. 2. 3. 4. 5.] 

7.3 花式索引

花式索引指的是利用整数数组进行索引

花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行

花式索引跟切片不一样,它总是将数据复制到新数组中

示例1,类似整数数组索引法,如下

import numpy as np

x = np.arange(32).reshape((8, 4))  # 传入倒序索引
print(x[[4, 2, 1, 7]])
print(x[[-4, -2, -1, -7]])

输出结果:

[[16 17 18 19]
 [ 8  9 10 11]
 [ 4  5  6  7]
 [28 29 30 31]]
[[16 17 18 19]
 [24 25 26 27]
 [28 29 30 31]
 [ 4  5  6  7]] 

示例2,np.ix_,对取出位置的坐标处,再进行排列组合,如下

1: x[1,0] x[1,3] x[1,1] x[1,2]
5: x[5,0] x[5,3] x[5,1] x[5,2]
7: x[7,0] x[7,3] x[7,1] x[7,2]
2: x[2,0] x[2,3] x[2,1] x[2,2]

import numpy as np

x = np.arange(32).reshape((8, 4))
print(x[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])])  # 输出4*4矩阵
# 其元素分别是
# x[1,0] x[1,3] x[1,1] x[1,2]
# x[5,0] x[5,3] x[5,1] x[5,2]
# x[7,0] x[7,3] x[7,1] x[7,2]
# x[2,0] x[2,3] x[2,1] x[2,2]
# 相当于:
# y=np.array([[x[1,0], x[1,3], x[1,1], x[1,2]],\
#             [x[5,0], x[5,3], x[5,1],x[5,2]],\
#             [x[7,0] ,x[7,3], x[7,1], x[7,2]],\
#             [x[2,0], x[2,3], x[2,1], x[2,2]]])

输出结果:

[[ 4  7  5  6]
 [20 23 21 22]
 [28 31 29 30]
 [ 8 11  9 10]] 

八:Numpy广播

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行

如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘;这要求维数相同,且各维度的长度相同

如下图,会为b进行补充,让其与a同规模shape

  

示例,当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制,如下

import numpy as np

# 当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。
a = np.array([1, 2, 3])
b = np.array([[0, 0, 0], [10, 10, 10], [20, 20, 20], [30, 30, 30]])
c = a + b
print(c)

输出结果:如1+20 2+20 3+20输出那一行 为 21 22 23

[[ 1  2  3]
 [11 12 13]
 [21 22 23]
 [31 32 33]] 

九:ufunc函数 算术运算

ufunc是universal function的简称,它是一种能对数组每个元素进行运算的函数

Numpy的许多ufunc函数都是用C实现的,因此它们的运算速度非常快

值得注意的是,对于等长度的ndarray,np.sin()比math.sin()要快,但是对于单个数值,math.sin()比较快 

Numpy提供了的许多ufunc函数,它们和相应的的运算符运算结果相同,示例如下

import numpy as np

a = np.arange(0, 4)  # [0 1 2 3]
b = np.arange(1, 5)  # [1 2 3 4]
res1 = np.add(a, b)
print(res1)
res2 = a + b
print(res2)

# >>> np.substract(a,b)		# 减法
# >>> np.multiply(a,b)		# 乘法
# >>> np.divide(a,b)		# 如果两个数字都为正数,则为整数除法
# >>> np.power(a,b)		# 乘方

输出结果:

[1 3 5 7]
[1 3 5 7] 

十:ufunc函数 比较运算

使用==,>对两个数组进行比较,会返回一个布尔数组

每一个元素都是对应元素的比较结果,示例如下

1<3为True;2<2为False;3<1为False

import numpy as np

a = np.array([1, 2, 3]) < np.array([3, 2, 1])
print(a)

输出结果:

[ True False False]

布尔运算在Numpy中也有对应的ufunc函数

如下图所示

十一:Numpy函数库 随机数

Numpy提供了大量对于数组运算的函数。可以简化逻辑,提高运算速度

Numpy产生随机数的模块在random里面,其中有大量的分布

示例如下

import numpy as np

from numpy import random as nr

np.set_printoptions(precision=2)  # 显示小数点后两位

r1 = nr.rand(4, 3)
r2 = nr.poisson(2.0, (4, 3))
print(r1)
print(r2)

输出结果:

[[0.7  0.65 0.72]
 [0.8  0.99 0.35]
 [0.55 0.26 0.25]
 [0.33 0.24 0.88]]
[[1 2 3]
 [2 2 5]
 [6 4 1]
 [5 2 1]]

十二:Numpy函数库 求和、平均值、方差

示例1,sum,如下

import numpy as np

np.random.seed(42)
a = np.random.randint(0, 10, size=(4, 5))

res = np.sum(a)
print(res)

输出结果:96

示例2,axis,如下

import numpy as np

np.random.seed(42)
a = np.random.randint(0, 10, size=(4, 5))

res1 = a
print(res1)
res2 = np.sum(a, axis=1)  # 行
print(res2)
res3 = np.sum(a, axis=0)  # 列
print(res3)

 输出结果: 3个结果值,分别为

[[6 3 7 4 6]
 [9 2 6 7 4]
 [3 7 7 2 5]
 [4 1 7 5 1]]
[26 28 24 18]
[22 13 27 18 16]

示例3,keepdims可以保持原来数组的维数 

import numpy as np

np.random.seed(42)
a = np.random.randint(0, 10, size=(4, 5))

res1 = np.sum(a, 1, keepdims=True)
print(res1)
res2 = np.sum(a, 0, keepdims=True)
print(res2)

输出结果:2个结果,分别为

[[26]
 [28]
 [24]
 [18]]
[[22 13 27 18 16]] 

十三:Numpy函数库 大小与排序

Numpy在排序等方面常用的函数如下: 

min,max都有axis,out,keepdims等参数,我们来看其他函数,

示例1如下,maxinum返回两组矩阵广播计算后的结果

import numpy as np

a = np.array([1, 3, 5, 7])
b = np.array([2, 4, 6])
res = np.maxinum(a[None, :], b[:, None])  # maxinum返回两组矩阵广播计算后的结果
print(res)

输出结果:

[[2 3 5 7],

 [4 4 5 7],

 [6 6 6 7]]

sort()对数组进行排序会改变数组排序的内容,返回一个新的数组。axis的默认值是-1,即按最终轴进行排序axis=0对每列上的值进行排序

示例2 ,如下

import numpy as np

a = np.array([
    [4, 7, 4, 5],
    [2, 7, 3, 5],
    [6, 6, 6, 7]
])
b = np.sort(a)
print(b)

输出结果:

[[4 4 5 7]
 [2 3 5 7]
 [6 6 6 7]] 

import numpy as np

a = np.array([
    [4, 7, 4, 5],
    [2, 7, 3, 5],
    [6, 6, 6, 7]
])
b = np.sort(a, axis=0)
print(b)

 输出结果:

[[2 6 3 5]
 [4 7 4 5]
 [6 7 6 7]]

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenruhan_QAQ_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值