Python数据分析 --- Numpy库
本文系统介绍了NumPy数组的核心操作,主要涵盖以下内容:1)数组创建方法,包括从列表/元组转换、使用arange/linspace生成序列、随机数生成以及文件读写;2)数组属性统计,包括尺寸、最值、分位数等计算;3)形状变换操作,如reshape、转置、升维降维等;4)数组分解与组合,包括切片索引、拼接拆分等;5)条件筛选与抽样;6)矩阵运算与广播机制;7)通用函数(ufunc)及其方法;8)N
array的创建与生成
使用列表或元组
np.array(<列表或元组>)
转换:np.asarray(<列表或元组>)
使用arange
生成一个一维的向量。
- 连续的一维向量,例如从0到N-1
使用linspace或logspace
np.linspace:
三个输入参数:开头、结尾、数量
np.linespace
四个输入参数:开头、结尾、数量、base=
使用zeros或ones
快速生成全0或全1数组。默认为float类型。np.zeros_like()或np.ones_like()生成与给定数组shape一样的全0、全1数组,比如需要Mask某些位置的时候。
使用random
新的API创建np.random.default_rng()先生成Generator,在此基础上,生成各种分布的数据。
用法:用于随机生成训练、测试数据;神经网络初始化。
例子:
rng = np.random.default_rng()
# 生成连续均匀分布
r1 = rng.random((2,3))
# 指定上下界的连续均匀分布
r2 = rng.uniform(0,1,(2,3))
# 随机整数(离散均匀分布)
r3 = np.random.randint(0,10,(2,3))
r4 = rng.integers(0,10,(2,3))
# 标准正态分布
r5 = rng.standard_normal((2,3))
# 高斯分布
r6 = rng.normal(0,1,(2,3))
从文件读取
加载存储好的权重参数或预处理好的数据集。比如训练好的模型参数加载到内存里用来提供推理服务,或者耗时很久的预处理数据直接存起来,多次实验时不需要重新处理。
# 直接将给定矩阵存为 a.npy
np.save('./data/a', np.array([[1, 2, 3], [4, 5, 6]]))
# 可以将多个矩阵存在一起,名为 `b.npz`
np.savez("./data/b", a=np.arange(12).reshape(3, 4), b=np.arange(12.).reshape(4, 3))
# 和上一个一样,只是压缩了
np.savez_compressed("./data/c", a=np.arange(12).reshape(3, 4), b=np.arange(12.).reshape(4, 3))
# 加载单个 array
np.load("data/a.npy")
# 加载多个,可以像字典那样取出对应的 array
arr = np.load("data/b.npz")
统计和属性
- 尺寸相关
- 最大、最小、中位、分位值等
- 平均、求和、标准差等
两个重要的特性:
- 按维度(axis)求结果。
- 对于二维数组来讲,0表示行,1表示列;表示沿着「行/列」操作。
- 计算后保持维度(
keepdims=True)。
尺寸相关
arr.ndim:维度arr.shape:形状,返回一个tuplearr.size:数据量
最值、分位数
分位数:可以是0-1的任意小数(表示对应分位),而分位数并不一定在原始的array中。np.quantile(arr,q,axis,keepdims)
均值:
np.average()np.mean()
累计求和:np.cumsum()
标准差:np.std()
方差:np.var()
形状与转换
改变形状
将多维数组打平:arr.ravel()
拓展一个维度(升维):np.expand_dims(arr, axis)
去除一个维度(降维):np.squeeze(arr, axis)
改变形状——生成一个新的arr
arr.reshape()
另一种变换形状——原地变换arr.resize()
- 不能用-1
- resize不一定和原来的元素数量一样多
- refcheck:设置为_False_,元素数量超出时,截断;元素数量不足时,0填充。
np.resize()
不同之处:元素数量不够时,会自动复制。
反序
使用索引:
对于一维数组、字符串:arr[: : -1]
对于二维数组:可以在不同的维度上操作
转置
一维数组转置还是它本身。
对于二维矩阵:arr.T
对于超过二维的张量:np.transpose(),可以指定axes。
分解和组合
切片与索引
通过对已有的array进行操作而得到的「部分」元素的过程。
核心操作:start:stop:step
把处理的按维度分开,不处理的维度统一用:或...代替。在操作时,首先关注「,」的位置。
拼接
将已有的几个array进行拼接以形成更大的array。比如不同类型特征的拼接。
拼接函数:np.concatenate:默认是按照 axis=0 拼接。
堆叠函数:np.stack:会增加一个维度。
其他(也是拼接):
竖直按行拼接np.vstack(),等同于np.concatenate()
水平按列拼接np.hstack(),等同于np.concatenate((arr1,arr2),axis=1)
关于array的条件判断:
不能直接使用if判断array是否符合某个条件,只能使用any()或all()。
分拆
将array拆成想要的几份。
方法:np.split()
分拆的axis是对该维度进行拆分,默认为_axis=0_。
其他函数:vsplite()、hsplite
筛选和过滤
条件筛选
Mask与异常值处理np.where(<condition>, x, y):满足条件,则输出x(或者arr本身),否则输出y。np.where(<condition>)
返回值:包含几个数组的(array几个维度)的tuple,分别对应满足条件元素的各维坐标。
提取(按条件)
提取指定条件的值:np.extract(<condition>, arr)
提取唯一值:np.unique(arr)
上面函数的返回值均为一维向量。
抽样(按分布)
rng.choice(<集合>,<样本大小>,replace= ,p)(新的API)
- 第一个参数是要抽样的集合,如果是一个整数,则表示从 0 到该值
- 第二个参数是样本大小
- 第三个参数表示结果是否可以重复
- 第四个参数表示出现的概率,长度和第一个参数一样
最大最小值index(特殊值)
np.argmax(arr, axis=):返回指定维度中最大值的索引。np.argsort(arr, axis=1):默认按行(axis = 1)排序的索引
矩阵和操作(运算)
算术(四则运算及其他基础算术)
加减乘除、开方(sqrt)、平方、对数(log)、minimum(逐元素地比较两个数组的最小值)、maximum()、四舍五入(round、floor、ceil)、求余数(mod)。
广播
处理不同形状的array时,较小的数组会在较大的数组上进行“广播”。
通用函数(ufunc)
定义:对ndarray进行逐元素的操作。同时支持数组广播、类型转换等。Numpy中的所有通用函数都是np.ufunc的实例。
可选关键字参数:
out=:主要是用来存储运算结果。where=:确定哪些可以存储。
ufunc数量很多,包括数学运算、三角函数、位操作、逻辑函数、浮点函数等。
https://numpy.org/devdocs/reference/ufuncs.html#available-ufuncs
ufunc支持的方法
ufunc支持以下方法:
- reduce:沿着某个维度累积
- accumulate:所有元素累积
- reduceat:沿着某个维度指定的slice累积
- outer:对A和B中所有元素对运算
- at:对指定索引的元素的执行无缓冲的就地运算
reduce函数
ufunc.reduce(array, axis=0, dtype=None, out=None, keepdims=False, initial=<no value>, where=True)
- array:数组
- axis:维度/轴
- dtype:数据类型
- out:输出结果存储在哪里
- where:确定哪些可以存储
- keepdims:是否保持维度
- initial:初始值
矩阵相关?
- 乘法:
np.dot(a,b)或a.dot(b) - 矩阵乘法:
np.mutmul()(等同于@写法) - 内积:
np.inner() - 向量点积:
np.vdot() - 行列式:
np.linalg.det(c) - 逆矩阵(方阵):
np.linalg.inv(c)
一些核心概念
常量
特殊值
| 名称 | 值(np.) |
|---|---|
| 自然对数 | e |
| π \pi π | pi |
| 0 | PZERO |
| -0 | NZERO |
| 空值 | nan或NAN或NaN |
| 正无穷 | inf |
| 负无穷 | NINF |
np.nan是一个值,两个np.nan不相等,即使它们同属于同一个类型。- 判断类函数(isxx)
isnanisinf、isposinf、isneginf、isfinite
数据类型
数据类型对象
数据类型对象描述了如何解释与数组项对应的固定大小的内存块中的字节。主要包括以下几个方面(当然有很多其他信息):
- 数据类型
- 数据大小
- 数据的顺序
- 如果是「结构化数据类型」则是其他数据类型的集合
- 如果数据类型是子数组,它的形状和数据类型
- bool:
bool8,bool_,不是 int - int:
int8/byte,int16/short,int32,int64/longlong,int_ - uint:无符号类型,表示
unsigned,对应 int - float:
float16/half,float32/single,float64/double,float_ - complex:复数,
complex64,complex128,complex_ - str:
str0,str_,表示 unicode 编码 - bytes:
bytes_,string_ - datetime/timedelta
- structed array
后面的数字表示一个数字在内存中占几位,一般比较推荐使用这种表示;带下划线的表示 python 的数据类型,numpy 可以自动将 python 的类型转为它;此外,浮点数还支持不同精度以及扩展精度。
建议在创建 array 时指定数据类型(提高性能、节省内存、思考数据的表示范围做到心中有数),且使用统一的数据类型计算。
大小
int默认64位,超出64位表示的范围,自动转为uint64
查看数组所占字节数:arr.nbytes
显示整数类型的机器限制:np.iinfo(np.int64)
显示浮点数类型的机器限制:np.finfo(np.float32)
顺序
字节顺序(Endianness)在计算机科学中指内存中字节的排列顺序。字节的排列有两个通用规则:
- 将低位放在较小的地址处,高位放在较大的地址处,称为小端序(little-endian)。
- 与上面相反的就是大端序(big-endian)。
![![[Pasted image 20241120213203.png]]](https://i-blog.csdnimg.cn/direct/68df1935024a4f85a98590f81fb0eb3a.png)
在 numpy 中,dtype 的每个类型都可以用一个字符表示,而使用字符表示时,可以增加字节序。
常见支持的字符表示如下:(大小写表示无符号和有符号)
| Format | C Type | Python Type | Standard Size |
|---|---|---|---|
? |
_Bool |
bool |
1 |
b/B |
char |
int |
1 |
h/H |
short |
int |
2 |
i/I |
int |
int |
4 |
l/L |
long |
int |
4 |
q/Q |
long |
int |
8 |
e |
half |
float |
2 |
f |
float |
float |
4 |
d |
double |
float |
8 |
复杂类型:
c:复数浮点m/M:timedelta/datetimeO:Python对象U:Unicode字符串V:voidS/a:零终止字节(不推荐)
参考:https://docs.python.org/3/library/struct.html
字节序有以下几种:(默认为 =)
| Character | Byte Order | Size |
|---|---|---|
= |
native | standsize |
< |
little-endian | standsize |
> |
big-endian | standsize |
| 字节顺序常用于不同设备(字节序不同)之间数据交互,也可以互相转换。 |
结构化数组
结构化数组:数据类型是一组(而不是只有一个)不同的数据类型的数组,常用于计算时需要将多种不同类型的数据放在一起的场景。
一维的结构化数组:dtype中的每一个tuple对应“每一个元素”
arr = np.array(
[('Rex', 9, 81.0), ('Fido', 3, 27.0)],
dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')]
)
多维的结构化数组:将每个元素重复多遍
marr = np.array([
[1, 2, 5],
[4, 5, 7],
[7, 8 ,11],
[10, 11, 12]
], dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'U3'), ('u', 'i8'), ('v', 'f8')])
marr
zeros 和 ones 和正常接口一样,可以快速创建多维(结构化)数组。
# zeros 会有不同反应,注意第一个元素是空
np.zeros((2, 3), dtype=[('a', 'S1'), ('b', 'i4')])
np.ones((2, 3), dtype=[('a', 'S1'), ('b', 'i4')])
时间数组
区别于Python的datetime,Numpy使用的是datetime64。
即,从1970年1月1日0时0分0秒起,常见的单位包括:年(Y)、月(M)、周(W)、日(D)、时(h)、分(m)、秒(s)、微秒(ms),及 NAT(Not a Time)。
支持arange操作
np.arange("2020-01", "2021-01-02T00:00:00", dtype="datetime64[M]")
支持转回字符串
np.datetime_as_string(t1)
数组对象
ndarray
array
自定义数组容器
子类化与标准
![![[core_concepts.png]]](https://i-blog.csdnimg.cn/direct/6e504a81864d4eff9b3ddaec4cece99e.png)
函数
np.bincount()函数
用于统计一个非负数组中元素的出现次数,使用样式如下:
np.bincount(x, weights=None, minlength=None)
返回值:默认为长度为n+1的数组,其索引i代表bin的编号(从0到n)。
每个bin存放着值的出现次数,也就是索引i表示数值i出现在数组x的出现的次数。
参数weights:表示数组x每个位置的权重(默认为1)。
参数minlength:指定了bin的最小长度,且最小长度不会低于数组的最大值加1。
![![[Pasted image 20241118162813.webp]]](https://i-blog.csdnimg.cn/direct/a2247bcacf3c4ca2b0a3d2b2de20dca9.webp)
随手记
np.clip(a, a_min, a_max, out=None)
- a:数组
- a_min:最小值
- a_max:最大值
将数组中的元素限制到 a_min 和 a_max之间,小于a_min的元素使其等于a_min,大于 a_max 的元素使其等于a_max。
更多推荐
![![[Pasted image 20241120150730.png]]](https://i-blog.csdnimg.cn/direct/185348915e6242afac3304b627d09d48.png)
所有评论(0)