数据处理与统计分析之NumPy详解
1 简介1.1 概述NumPy(Numerical Python)是Python数据分析必不可少的第三方库NumPy的出现一定程度上解决了Python运算性能不佳的问题,同时提供了更加精确的数据类型,使其具备了构造复杂数据类型的能力。本身是由C语言开发,是个很基础的扩展,NumPy被Python其它科学计算包作为基础包,因此理解np的数据类型对python数据分析十分重要。NumPy重在数值计算,主要用于多维数组(矩阵)处理的库。用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效的多1.2 NumPy 与Python 原生列表的核心差异特性Python 列表NumPy ndarray元素类型可混合类型(如[1, "a"])强制统一类型内存布局分散存储,内存开销大连续存储,内存利用率高运算效率需循环,速度慢(Python 解释器)向量化运算,C 底层,速度快维度支持嵌套列表模拟多维,操作繁琐原生支持多维,内置多维操作数学函数需手动实现 / 调用 math 模块内置丰富的向量化数学函数切片会创建一个新的列表,可以理解成副本切片是视图,不是副本!大小修改动态增删固定大小,修改创建新数组2 主要功能NumPy重要功能如下:高性能科学计算和数据分析的基础包ndarray,多维数组,具有矢量运算能力,快速、节省空间矩阵运算,无需循环,可完成类似Matlab中的矢量运算用于读写磁盘数据的工具以及用于操作内存映射文件的工具3 属性3.1 概述ndarray.ndim定义:数组的维度(秩),返回整数通俗理解:数组有几个维度 → 一维是线、二维是面、三维是体示例:一维数组ndim=1,二维矩阵ndim=2,三维数组ndim=3ndarray.shape定义:数组每个维度的大小,返回整数元组通俗理解:描述数组的「形状」,直观表示几行几列 / 几层几行几列一维数组:(元素个数,)二维数组:(行数, 列数)三维数组:(层数, 行数, 列数)ndarray.size定义:数组中总元素的个数,返回整数通俗理解:数组里一共有多少个数据关键关联:size = shape 中所有数字的乘积ndarray.dtype定义:数组中元素的数据类型,返回 dtype 对象通俗理解:数组所有元素的统一类型(ndarray 强制要求所有元素类型一致)常见类型:int32/int64(整数)、float32/float64(浮点数)、bool(布尔值)ndarray.itemsize定义:数组单个元素占用的字节数,返回整数(单位:字节)通俗理解:每个数据占用的内存空间大小关键关联:itemsize 由 dtype 决定int32/float32 → 4 字节int64/float64 → 8 字节bool → 1 字节3.2 代码演示importnumpyasnp# 创建 2行3列 的二维数组(指定数据类型为32位整数)arr=np.array([[1,2,3],[4,5,6]],dtype=np.int32)# 打印所有核心属性print("数组维度(ndim):",arr.ndim)# 2print("数组形状(shape):",arr.shape)# (2, 3)print(len(arr.shape))print("总元素数(size):",arr.size)# 6print("元素类型(dtype):",arr.dtype)# int32print("单元素字节(itemsize):",arr.itemsize)# 43.3 属性核心关联维度关系:len(arr.shape) = arr.ndimarr.shape 是一个元组,元组里有几个数字,就代表数组有几个维度;而 arr.ndim 就是数组的维度数量。所以:元组的长度 = 维度数 → len(arr.shape) = arr.ndim总数关系:arr.size = arr.shape[0] × arr.shape[1] × ...内存关系:数组总字节数 = arr.size × arr.itemsize(总字节数可直接用拓展属性arr.nbytes获取)ndarray.nbytes:数组所有元素占用的总字节数(= size × itemsize)3.4 axis 参数的可视化解释axis 值对应 shape 位置官方叫法通俗理解操作效果axis=0shape [0](行数)行维度纵向 / 上下压缩行,保留列axis=1shape [1](列数)列维度横向 / 左右压缩列,保留行如果实在迷糊 就记忆 axis=N 就是沿着第 N 个维度压扁 / 聚合 / 切割,这个维度会消失!importnumpyasnp arr=np.array([[1,2,3],# 第0行[4,5,6]# 第1行])# shape = (2行, 3列) → (axis=0, axis=1)axis=0纵向(行方向) 列0列1列2↓ ↓ ↓[1,2,3]→ 行0[4,5,6]→ 行1↑ ↑ ↑ axis=0是**上下垂直**方向,把行压掉,算每列的结果 axis=1横向(列方向) 行0→[1→2→3]行1→[4→5→6]←→ axis=1是**左右水平**方向,把列压掉,算每行的结果arr=np.array([[1,2,3],[4,5,6]])# axis=0:按列求和(纵向加,压掉行)print(arr.sum(axis=0))# [1+4, 2+5, 3+6] → [5,7,9]# axis=1:按行求和(横向加,压掉列)print(arr.sum(axis=1))# [1+2+3, 4+5+6] → [6,15]4 创建ndarray4.1 概述NumPy数组是一个多维的数组对象(矩阵),称为ndarray,具有矢量算术运算能力和复杂的广播能力,并具有执行速度快和节省空间的特点。注意:ndarray的下标从0开始,且数组里的所有元素必须是相同类型。4.2 代码实现4.2.1 写法1: array()函数可以把Python列表转成ndarray对象.importnumpyasnp# 1. 创建Python的列表.my_list=[1,2,3,4,5]# 2. 把上述的列表转成ndarray对象.arr1=np.array(my_list)# 等价于: arr1 = np.array([1, 2, 3, 4, 5])# 3. 打印arr1的类型, 和其元素类型.print(f'arr1的数据类型是:{type(arr1)}')print(f'arr1中元素的类型是:{arr1.dtype}')4.2.2 写法2: arange(起始值,结束值,步长)函数类似于Python的range()函数importnumpyasnp# 1. 创建1个ndarray数组, 存放1到10的数字.arr2=np.arange(1,10,2,dtype=np.float64)# 左闭右开# 2. 打印arr2的类型, 和其元素类型.print(f'arr2的数据类型是:{type(arr2)}')print(f'arr2中元素的类型是:{arr2.dtype}')print(f'arr2的元素是:{arr2}')4.2.3 写法3: 获取随机的数组即: rand(), randint(), uniform()importnumpyasnp# 演示rand()函数# 1. 创建1个3行4列, 范围是0.0 ~ 1.0之间的随机数组.arr3=np.random.rand(3,4)print(f'arr3的元素是:{arr3}')print(f'arr3的数据类型是:{type(arr3)}')print(f'arr3中元素的类型是:{arr3.dtype}')# float64# 演示randint()函数, 获取一个指定范围内的随机整数.# 1. 创建1个3行4列, 范围是-3 ~ 10之间的随机数组.arr4=np.random.randint(-3,10,size=(3,4))# 包左不包右print(f'arr4的元素是:{arr4}')print(f'arr4的数据类型是:{type(arr4)}')print(f'arr4中元素的类型是:{arr4.dtype}')# int32# 演示uniform()函数, 获取一个指定范围内的随机小数.# 1. 创建1个3行4列, 范围是-2.0 ~ 5.0之间的随机数组.arr5=np.random.uniform(-2.0,5.0,(3,4))print(f'arr5的元素是:{arr5}')print(f'arr5的数据类型是:{type(arr5)}')print(f'arr5中元素的类型是:{arr5.dtype}')# float644.2.4 写法4: zeros(), ones(), empty()importnumpyasnp#演示zeros()函数, 创建一个全为0的数组.# 1. 创建1个3行4列, 全为0的数组.arr6=np.zeros(shape=(3,4),dtype=np.int16)print(f'arr6的元素是:{arr6}')print(f'arr6的数据类型是:{type(arr6)}')print(f'arr6中元素的类型是:{arr6.dtype}')# 演示ones()函数, 创建一个全为1的数组.# 1. 创建1个3行4列, 全为1的数组.arr7=np.ones(shape=(3,4),dtype=np.int32)print(f'arr7的元素是:{arr7}')print(f'arr7的数据类型是:{type(arr7)}')print(f'arr7中元素的类型是:{arr7.dtype}')# 演示empty()函数, 创建指定形状的数组,仅分配内存空间但不初始化元素值,元素为内存中残留的垃圾值(非主动 “随机分配”,是内存原有残留值)# 1. 创建1个3行4列, 随机分配的数组.arr8=np.empty(shape=(3,4),dtype=np.int32)print(f'arr8的元素是:{arr8}')print(f'arr8的数据类型是:{type(arr8)}')print(f'arr8中元素的类型是:{arr8.dtype}')4.2.5 写法5: 等比和等差数列#演示logspace(), 创建一个等比数列.importnumpyasnp# 1. 创建1个1 ~ 1000之间的等比数列, 元素长度为: 5arr1=np.logspace(0,3,5)# 参1: 起始值,10的0次幂, 参2:结束值,10的3次幂, 参3:元素个数#注意:包左包右 np.logspace(0, 3, 5) 等价于 10^0, 10^0.75, 10^1.5, 10^2.25, 10^3# 2. 打印上述数组的信息.print(f'arr1的元素是:{arr1}')print