Numpy
1、概述
(一)、简介
- NumPy(Numerical Python)是Python数据分析必不可少的第三方库
- NumPy的出现一定程度上解决了Python运算性能不佳的问题,同时提供了更加精确的数据类型,使其具备了构造复杂数据类型的能力。
- 本身是由C语言开发,是个很基础的扩展,NumPy被Python其它科学计算包作为基础包,因此理解np的数据类型对python数据分析十分重要。
- NumPy重在数值计算,主要用于多维数组(矩阵)处理的库。用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效的多
(二)、功能
-
高性能科学计算和数据分析的基础包
-
ndarray,多维数组,具有矢量运算能力,快速、节省空间
-
矩阵运算,无需循环,可完成类似Matlab中的矢量运算
-
用于读写磁盘数据的工具以及用于操作内存映射文件的工具
2、Numpy属性
(一)、常见属性
numpy.dtype(object, align, copy) # 元素的类型
ndarray.ndim # 数组的秩,也就是数组的维度数量或者轴的数量
ndarray.shape # 数组的维度
ndarray.size # 元素总个数
ndarray.itemsize # 元素的大小(字节数)
(二)、例子
# 1. 构建1个3行5列的 ndarray对象(n维数字), 即: 3行5列.
arr = np.arange(15).reshape((3, 5)) # arange(15)类似于Python的range(15), 然后把0~15(包左不包右)的数据放到 3个 长度维5的一维数组中.
print(f'ndarray对象: {arr}') # ndarray对象.
print(f'数组的形状(维度): {arr.shape}') # (3, 5), 简单理解为: 3行5列
print(f'数组的轴: {arr.ndim}') # 2, 几维数组, 维度(轴)就是几.
print(f'数组的长度: {arr.size}') # 15, 即所有元素的个数.
print(f'数组的每个元素的类型: {arr.dtype}') # int64
print(f'数组的每个元素的大小(字节数): {arr.itemsize}') # 8
print(f'数组的类型: {type(arr)}') # <class 'numpy.ndarray'>
# 扩展: 上述的 shape, ndim, size等属性, 可以改写成: np.属性名(对象对)的形式.
print(f'数组的形状(维度): {np.shape(arr)}') # (3, 5), 简单理解为: 3行5列
print(f'数组的轴: {np.ndim(arr)}') # 2, 几维数组, 维度(轴)就是几.
print(f'数组的长度: {np.size(arr)}') # 15, 即所有元素的个数.
# print(f'数组的每个元素的类型: {np.dtype(arr)}') # 报错, 无该函数
# print(f'数组的每个元素的大小(字节数): {np.itemsize(arr)}') # 报错, 无该函数
# print(f'数组的类型: {np.type(arr)}') # 报错, 无该函数
3、ndarray对象
(一)、数组的方式创建
格式
# 细节: 数组的元素类型要统一
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
'''
object:数组或者嵌套的数列
dtype:数组元素的数据类型,可选
copy:对象是否需要复制,可选
order:创建数组的样式,C为行方向,F为列方向,A为任意方向
subok:默认返回一个与基类类型一致的数组
ndmin:指定生成数组的最小维度
'''
例如
# 1. 数组方式创建 ndarray对象(Numpy的核心对象, 即: n维数组)
arr1 = np.array([1, 2, 3])
print(f'arr的内容: {arr1}')
print(f'arr的类型: {type(arr1)}')
print(f'arr的元素类型: {arr1.dtype}') # int32
'''
arr的内容: [1 2 3]
arr的类型: <class 'numpy.ndarray'>
arr的元素类型: int32
'''
# 2. 数组方式创建 ndarray对象(Numpy的核心对象, 即: n维数组)
arr2 = np.array([1.1, 2.3, 3.5])
print(f'arr2的内容: {arr2}')
print(f'arr2的类型: {type(arr2)}')
print(f'arr2的元素类型: {arr2.dtype}') # float64
'''
arr2的内容: [1.1 2.3 3.5]
arr2的类型: <class 'numpy.ndarray'>
arr2的元素类型: float64
'''
(二)、创建空的ndarray对象
格式
# 细节: 3个函数, 获取的元素类型都是: float64
zero() # 创造一个全是0的矩阵
ones() # 创造一个全是1的矩阵
empty() # 创造一个内容随机的矩阵(随机依赖于内存,内存不变随机数不变)
zeros_like(a, dtype=None, order='K', subok=True, shape=None)
# 创建一个与给定数组具有相同形状的数组,元素全是0
'''
a:要创建相同形状的数组
dtype:创建数组的数据类型
order:数组在内存中的存储顺序,可选值为 'C'(按行优先)或 'F'(按列优先),默认为 'K'(保留输入数组的存储顺序)
subok:是否允许返回子类,如果为 True,则返回一个子类对象,否则返回一个与 a 数组具有相同数据类型和存储顺序的数组
shape:创建的数组的形状,如果不指定,则默认为 a 数组的形状
'''
numpy.ones_like(a, dtype=None, order='K', subok=True, shape=None)
# 创建一个与给定数组具有相同形状的数组
'''
a:给定要创建相同形状的数组
dtype:创建的数组的数据类型
order:数组在内存中的存储顺序,可选值为 'C'(按行优先)或 'F'(按列优先),默认为 'K'(保留输入数组的存储顺序)
subok:是否允许返回子类,如果为 True,则返回一个子类对象,否则返回一个与 a 数组具有相同数据类型和存储顺序的数组
shape:创建的数组的形状,如果不指定,则默认为 a 数组的形状
'''
例如
# 1. 演示 zeros()函数, 创建1个全是0的ndarray对象.
arr3 = np.zeros((3, 5)) # 维度: 3行5列, 1个二维数组, 它有3个元素(每个都是1维数组), 且每个一维数组有5个元素.
print(f'arr3的内容: {arr3}')
print(f'arr3的类型: {type(arr3)}')
print(f'arr3的元素类型: {arr3.dtype}') # float64
'''
arr3的内容: [[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
arr3的类型: <class 'numpy.ndarray'>
arr3的元素类型: float64
'''
# 2. 演示 ones()函数, 创建1个 全是1的 ndarray对象.
arr4 = np.ones((2, 3)) # 维度: 2行3列, 1个二维数组, 它有2个元素(每个都是1维数组), 且每个一维数组有3个元素.
print(f'arr4的内容: {arr4}')
print(f'arr4的类型: {type(arr4)}')
print(f'arr4的元素类型: {arr4.dtype}') # float64
'''
arr4的内容: [[1. 1. 1.]
[1. 1. 1.]]
arr4的类型: <class 'numpy.ndarray'>
arr4的元素类型: float64
'''
# 3. 演示 empty()函数, 创建1个 内容随机且依赖内存状态的 ndarray对象.
arr5 = np.empty((2, 3)) # 维度: 2行3列, 1个二维数组, 它有2个元素(每个都是1维数组), 且每个一维数组有3个元素.
print(f'arr5的内容: {arr5}')
print(f'arr5的类型: {type(arr5)}')
print(f'arr5的元素类型: {arr5.dtype}') # float64
'''
arr5的内容: [[1. 1. 1.]
[1. 1. 1.]]
arr5的类型: <class 'numpy.ndarray'>
arr5的元素类型: float64
'''
(三)、创建指定范围和步长的ndarray对象
格式
numpy.arange(start, stop, step, dtype) # 类似于python中的range()函数
例如
# 参1: 起始值(start), 参2: 结束值(不包括) stop, 参3: 步长, step. 参4: 数据类型, dtype
arr6 = np.arange(0, 10, 2, dtype=np.int64)
print(f'arr6的内容: {arr6}')
print(f'arr6的类型: {type(arr6)}')
print(f'arr6的元素类型: {arr6.dtype}') # float64
'''
arr6的内容: [0 2 4 6 8]
arr6的类型: <class 'numpy.ndarray'>
arr6的元素类型: int64
'''
(四)、创建二维数组
格式
matrix() # 创建二维的数组,mat()与该函数效果一致
例如
# 1. 创建2维矩阵.
# arr7 = np.mat('1 2 3;4 5 6')
arr7 = np.matrix('1 2 3;4 5 6')
print(f'arr7的内容: {arr7}')
print(f'arr7的类型: {type(arr7)}') # matrix类型是 ndarray类型的 子类型.
print(f'arr7的元素类型: {arr7.dtype}') # float64
'''
arr7的内容: [[1 2 3]
[4 5 6]]
arr7的类型: <class 'numpy.matrix'>
arr7的元素类型: int32
'''
# 2. 创建2维矩阵.
arr8 = np.mat('1,2,3;4,5,6')
print(f'arr8的内容: {arr8}')
print(f'arr8的类型: {type(arr8)}') # matrix类型是 ndarray类型的 子类型.
print(f'arr8的元素类型: {arr8.dtype}') # float64
'''
arr8的内容: [[1 2 3]
[4 5 6]]
arr8的类型: <class 'numpy.matrix'>
arr8的元素类型: int32
'''
# 3. 创建2维矩阵.
arr9 = np.mat(([1, 2, 3], [4, 5, 6])) # (第1个1维数组, 第2个一维数组...)
print(f'arr9的内容: {arr9}')
print(f'arr9的类型: {type(arr9)}') # matrix类型是 ndarray类型的 子类型.
print(f'arr9的元素类型: {arr9.dtype}') # float64
'''
arr9的内容: [[1 2 3]
[4 5 6]]
arr9的类型: <class 'numpy.matrix'>
arr9的元素类型: int32
'''
(五)、创建随机的ndarray对象
格式
random.rand() # 创建0.0~1.0之间的随机数
random.randint() # 指定范围内生成整数随机数
random.uniform() # 指定范围内生成小数随机数
random.randn()
例如
# 1. random.rand()函数, 创建0.0 ~ 1.0区间的随机数.
arr10 = np.random.rand(3, 5) # 3行5列
print(f'arr10的内容: {arr10}')
print(f'arr10的类型: {type(arr10)}') # <class 'numpy.ndarray'>
print(f'arr10的元素类型: {arr10.dtype}') # float64
'''
arr10的内容: [[0.53813533 0.44168178 0.1511361 0.77878695 0.78863361]
[0.05959302 0.72917081 0.37366742 0.50864748 0.72221538]
[0.81312235 0.80706018 0.34945499 0.21080258 0.64437881]]
arr10的类型: <class 'numpy.ndarray'>
arr10的元素类型: float64
'''
# 2. random.randint()函数, 可以指定范围, 生成: 整数的随机数
arr11 = np.random.randint(1, 10, size=(3, 5)) # 3行5列
print(f'arr11的内容: {arr11}')
print(f'arr11的类型: {type(arr11)}') # <class 'numpy.ndarray'>
print(f'arr11的元素类型: {arr11.dtype}') # float64
'''
arr11的内容: [[8 9 5 2 6]
[1 7 4 4 3]
[4 4 9 5 5]]
arr11的类型: <class 'numpy.ndarray'>
arr11的元素类型: int32
'''
# 3. random.uniform()函数, 可以指定范围, 生成: 小数的随机数
arr12 = np.random.uniform(1, 10, size=(3, 5)) # 3行5列
print(f'arr12的内容: {arr12}')
print(f'arr12的类型: {type(arr12)}') # <class 'numpy.ndarray'>
print(f'arr12的元素类型: {arr12.dtype}') # float64
'''
arr12的内容: [[2.84314753 5.22655245 6.17191338 9.47401406 4.99604169]
[2.56853946 5.87402435 5.00552884 3.89829494 4.66979043]
[2.2194954 5.81720869 1.90185452 7.55161239 7.3594193 ]]
arr12的类型: <class 'numpy.ndarray'>
arr12的元素类型: float64
'''
(六)、ndarray的类型转换
格式
astype() # 可以将ndarray转换成目标类型
例如
# 1. 创建1个 ndarray对象, 元素类型为: float64
arr13 = np.zeros((3, 5), dtype=np.float64)
print(arr13)
print(arr13.dtype) # float64
'''
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
float64
'''
# 2. 把上述的 arr13 从 float64 => int32
arr14 = arr13.astype(np.int32)
print(arr14)
print(arr14.dtype) # int32
'''
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]
int32
'''
(七)、等比和等差数列
格式
logspace() # 等比数列
linspace() # 等差数列
例如
# 1. logspace(): 等比数列, 默认是: 10的幂, 且: 包左包右
arr15 = np.logspace(1, 3, 5) # 生成10 ^ 1 ~ 10 ^ 3之间, 5个元素
print(f'arr15的内容: {arr15}')
print(f'arr15的类型: {type(arr15)}') # <class 'numpy.ndarray'>
print(f'arr15的元素类型: {arr15.dtype}') # float64
'''
arr15的内容: [ 10. 31.6227766 100. 316.22776602 1000. ]
arr15的类型: <class 'numpy.ndarray'>
arr15的元素类型: float64
'''
# 2. logspace(): 等比数列, 默认是: 10的幂, 且: 包左包右, 指定底数.
arr15 = np.logspace(1, 3, 5, base=2) # 生成2 ^ 1 ~ 2 ^ 3之间, 5个元素
print(f'arr15的内容: {arr15}')
print(f'arr15的类型: {type(arr15)}') # <class 'numpy.ndarray'>
print(f'arr15的元素类型: {arr15.dtype}') # float64
'''
arr15的内容: [2. 2.82842712 4. 5.65685425 8. ]
arr15的类型: <class 'numpy.ndarray'>
arr15的元素类型: float64
'''
# 3. linspace(): 等差数列, 默认: 包左包右.
arr16 = np.linspace(1, 10, 5) # 1 ~ 10之间的, 5个元素.
print(f'arr16的内容: {arr16}')
print(f'arr16的类型: {type(arr16)}') # <class 'numpy.ndarray'>
print(f'arr16的元素类型: {arr16.dtype}') # float64
'''
arr16的内容: [ 1. 3.25 5.5 7.75 10. ]
arr16的类型: <class 'numpy.ndarray'>
arr16的元素类型: float64
'''
# 4. linspace(): 等差数列, 默认: 包左包右. endpoint: 默认是True(即: 包括结束值)
arr17 = np.linspace(1, 10, 5, endpoint=False) # 1 ~ 10之间的, 5个元素.
print(f'arr17的内容: {arr17}')
print(f'arr17的类型: {type(arr17)}') # <class 'numpy.ndarray'>
print(f'arr17的元素类型: {arr17.dtype}') # float64
'''
arr17的内容: [1. 2.8 4.6 6.4 8.2]
arr17的类型: <class 'numpy.ndarray'>
arr17的元素类型: float64
'''
4、高级索引
(一)、整数数组索引
使用一个数组来访问另一个数组的元素
格式
y = x[rows, cols]
例如
x = numpy.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
rows = numpy.array([[0, 0], [3, 3]])
cols = numpy.array([[0, 2], [0, 2]])
y = x[rows, cols]
print(f'[0,0]、[0,2]、[3,0]、[3,2]的元素值为{y}')
(二)、布尔索引
通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组
格式
x[x > 指定值]
例如
# 筛选大于4的元素
x = numpy.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(f'之前的数组为{x}')
print(f'筛选大于4的元素为:')
print(x[x > 4])
# 使用~(取补运算符) 过滤 NaN
x = numpy.array([numpy.nan, 1, 2, numpy.nan, 3, 4, 5])
print(a[~numpy.isnan(x)])
(三)、花式索引
根据索引数组的值作为目标数组的某个轴的下标来取值,花式索引跟切片不一样,它总是将数据复制到新数组中
格式
# 一维数组
# 一维数组只有一个轴 axis = 0,所以一维数组就在 axis = 0 这个轴上取值
x1 = x[[0, 6]]
# 二维数组
# 1、传入顺序索引数组
x[[2, 4, 6, 8]]
# 2、传入倒序索引数组
x[[-2, -4, -6, -8]]
# 3、传入多个索引数组--np.ix_
'''
np.ix_ 函数就是输入两个数组,产生笛卡尔积的映射关系
例如:A = (a, b), B = (0, 1, 2)
A×B = {(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A = {(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
'''
x[np.ix_([2, 4, 6, 8],[1, 3, 2, 0])]
例如
# 一维数组
x = np.arange(9)
x1 = x[[0, 6]]
print(x2) # [0, 6]
# 二维数组
# 1、传入顺序索引数组
x = np.arange(36).reshape((9,4))
print (x[[2, 4, 6, 8]])
'''
[[ 8 9 10 11]
[16 17 18 19]
[24 25 26 27]
[32 33 34 35]]
'''
# 2、传入倒序索引数组
x = np.arange(36).reshape((9,4))
print (x[[-2, -4, -6, -8]])
'''
[[28 29 30 31]
[20 21 22 23]
[12 13 14 15]
[ 4 5 6 7]]
'''
# 3、传入多个索引数组--np.ix_
x = np.arange(36).reshape((9,4))
print (x[np.ix_([2, 4, 6, 8] ,[1, 3, 5, 7])])
'''
[[ 9 11 10 8]
[17 19 18 16]
[25 27 26 24]
[33 35 34 32]]
'''
5、函数
(一)、基本函数
格式
np.reshape # 调整数组的大小,通常返回的是非拷贝副本,即改变返回后数组的元素,原数组对应元素的值也会改变
np.ceil() # 向上最接近的整数,参数是 number 或 array
np.floor() # 向下最接近的整数,参数是 number 或 array
np.rint() # 四舍五入,参数是 number 或 array
np.isnan() # 判断元素是否为 NaN(Not a Number),参数是 number 或 array
np.multiply() # 元素相乘,参数是 number 或 array
np.divide() # 元素相除,参数是 number 或 array
np.abs() # 元素的绝对值,参数是 number 或 array
np.where(condition, x, y) # 三元运算符,x if condition else y
# 注意: 需要注意multiply/divide 如果是两个ndarray进行运算 shape必须一致
例如
# 1. 创建1个正太分布的 ndarray对象.
arr = np.random.randn(2, 3)
'''
-0.344227,-0.766068,1.536094
-0.153168,-0.029010,-0.351011
'''
# 2. 演示基本函数.
print(np.ceil(arr)) # 向上取整, 天花板数.
print(np.floor(arr)) # 向下取整, 地板数.
print(np.rint(arr)) # 四舍五入
print(np.isnan(arr)) # 判断是否是: 空值.
print(np.abs(arr)) # 绝对值
print(np.multiply(arr, arr)) # 乘法运算.
print(np.divide(arr, arr)) # 除法运算.
print(np.where(arr > 0, 1, -1)) # 转换, 大于0的 => 1, 否则 => -1
'''
[[-0. -0. 2.]
[-0. -0. -0.]]
[[-1. -1. 1.]
[-1. -1. -1.]]
[[-0. -1. 2.]
[-0. -0. -0.]]
[[False False False]
[False False False]]
[[0.34422725 0.76606825 1.53609391]
[0.15316788 0.0290104 0.35101139]]
[[1.18492401e-01 5.86860558e-01 2.35958451e+00]
[2.34604003e-02 8.41603241e-04 1.23208996e-01]]
[[1. 1. 1.]
[1. 1. 1.]]
[[-1 -1 1]
[-1 -1 -1]]
'''
(二)、统计函数
格式
sum() # 求矩阵和
cumsum() # 前缀和,输出列表
例如
# 1. 创建1个 ndarray对象.
arr = np.arange(12).reshape(3, 4) # 3行4列, 二维数组
'''
0,1,2,3
4,5,6,7
8,9,10,11
'''
# 2. 统计函数
print(np.sum(arr)) # 求和: 66
print(np.cumsum(arr)) # 求和: [ 0 1 3 6 10 15 21 28 36 45 55 66]
'''
66
[ 0 1 3 6 10 15 21 28 36 45 55 66]
'''
# 3. 按行或者列进行求和, axis=0 或者 1 0 => 按列计算, 1 => 按行计算
print(np.sum(arr, axis=0)) # [12 15 18 21]
print(np.sum(arr, axis=1)) # [ 6 22 38]
'''
[12 15 18 21]
[ 6 22 38]
'''
(三)、判断相关
格式
any() # 任意1个值满足条件即可, 类似于Python中的 or
all() # 要求所有的元素都要满足, 类似于Python的and
例如
# 1. 创建1个 ndarray对象.
arr = np.random.randn(2, 3)
'''
1.297382,0.299214,0.995814
0.973208,-1.486949,-0.408149
'''
# 2. 演示 any()函数: 任意1个值满足条件即可, 类似于Python中的 or
print(np.any(arr > 0)) # True
# 3. 演示 all()函数: 要求所有的元素都要满足, 类似于Python的and
print(np.all(arr > 0)) # False
(四)、去重相关
格式
unique() # 去重
去重
# 1. 创建1个 ndarray对象.
arr = np.array([[3, 2, 1, 2], [2, 6, 5, 5]])
# 2. 对上述的 ndarry去重
print(np.unique(arr)) # [1 2 3 5 6]
(五)、排序相关
格式
sort(容器) # 返回1个新的ndarray对象
容器.sort() # 对自身进行排序
去重
# 1. 创建1个 ndarray对象.
arr = np.array([3, 1, 2, 5, 6])
print(f'排序前: {arr}')
# 2. 排序, 方式1: np.sort(arr) => 返回1个新的ndarray对象.
# np.sort(arr)
# print(f'排序后: {arr}')
new_arr = np.sort(arr)
print(f'排序后: {new_arr}')
# 3. 排序, 方式2: arr.sort() => 对自身进行排序.
arr.sort()
print(f'排序后: {arr}')
6、运算
(一)、基本运算
格式
+, -
例如
# 1. 创建两个 ndarray对象.
arr1 = np.array([10, 20, 30, 40])
arr2 = np.arange(4)
# 2. 打印上述的两个对象.
print(f'arr1: {arr1}')
print(f'arr2: {arr2}')
# 3. 基本运算, 并输出结果.
arr3 = arr1 - arr2
print(f'arr3: {arr3}') # [10 19 28 37]
(二)、矩阵运算
格式
multiply() # 哈达玛积(元素积),对应位置上的元素乘
dot() # 乘积,行乘列后的和,为当前元素
例如
# 1. 创建两个 ndarray对象.
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(f'arr1: {arr1}')
print(f'arr2: {arr2}')
# 2. 矩阵运算, 场景1: A的行数 = B的行数 且 A的列数 = B的列数
# arr3 = arr1 * arr2
arr3 = np.multiply(arr1, arr2)
print(f'arr3: {arr3}') # [[ 1 4 9], [16 25 36]]
# 3. 矩阵运算, 场景2: A的列数 = B的行数 且 A的列数 != B的列数
# 假设: A => 2行3列, B => 3行2列
# 3.1 创建两个ndarray对象.
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[1, 2], [4, 5], [-6, 7]])
print(f'arr1: {arr1}')
print(f'arr2: {arr2}')
# 3.3 矩阵运算.
print(np.dot(arr1, arr2))
print(arr1.dot(arr2)) # [[-9, 33], [-12, 75]]
4650

被折叠的 条评论
为什么被折叠?



