Numpy
ndarray对象基本应用
- 标准的Python中用列表(list)保存一组值,可以当作数组使用。但由于列表的元素可以是任何对象,因此列表中保存的是对象的指针。对于数值运算来说,这种结构显然比较浪费内存和CPU计算。
- Python 提供了array 模块,它和列表不同,能直接保存数值,但是由于它不支持多维数组,无各种运算函数,因此也不适合做数值运算。
- NumPy 的诞生弥补了这些不足,NumPy 提供了两种基本的对象:ndarray(n-dimensional array object)和ufunc(universal function object)。
- ndarray是存储单一数据类型的多维数组,ndarray 中的每个元素在内存中都有相同存储大小的区域。而ufunc 则是能够对数组进行处理的函数。
1 #NumPy生成数组时一般会有一个参数dtype,它的默认值一般为float浮点型。 2 np.array([1, 2, 3, 4]) 3 np.arange(0, 1, 0.1) 4 np.random.randint(0,10,size=(4,5)) 5 # logspace函数和linspace类似,创建等比数列。 6 #下面的例子产生1(10^0)到100(10^2)、有20个元素的等比数列 7 np.logspace(0, 2, 20) 8 9 np.empty((2,3),np.int) #只分配内存,不对其进行初始化 10 # array([[ 32571594, 32635312, 505219724], 11 # [ 45001384, 1852386928, 665972]]) 12 13 np.zeros(4, np.float) #元素类型默认为np.float,因此这里可以省略 14 #array([ 0., 0., 0., 0.]) 15 16 # 使用frombuffer, fromstring, fromfile,fromfunction等函数可以从字节序列、文件创建数组。下面以fromfunction为例: 17 #fromfunction函数的第一个参数为计算每个数组元素的函数,第二个参数为数组的大小(shape)。 18 def func(i): 19 return i%4+1 20 np.fromfunction(func, (10,)) 21 # array([ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2.]) 22 23 # 下面的例子创建一个二维数组表示九九乘法表,输出的数组a中的每个元素a[i, j]都等于func2(i, j): 24 def func2(i, j): 25 return (i+1) * ( j+1) 26 a = np.fromfunction(func2, (9,9)) 27 # a = array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.], 28 # [ 2., 4., 6., 8., 10., 12., 14., 16., 18.], 29 # [ 3., 6., 9., 12., 15., 18., 21., 24., 27.], 30 # [ 4., 8., 12., 16., 20., 24., 28., 32., 36.], 31 # [ 5., 10., 15., 20., 25., 30., 35., 40., 45.], 32 # [ 6., 12., 18., 24., 30., 36., 42., 48., 54.], 33 # [ 7., 14., 21., 28., 35., 42., 49., 56., 63.], 34 # [ 8., 16., 24., 32., 40., 48., 56., 64., 72.], 35 #[ 9., 18., 27., 36., 45., 54., 63., 72., 81.]]) 36 37 #shape与reshape 38 #可以通过修改数组的shape属性,在保持数组元素个数不变的情况下,改变数组每个轴的长度。 39 a = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]]) 40 a.shape=4,3 41 #a = array([[ 1, 2, 3],[ 4, 4, 5],[ 6, 7, 7],[ 8, 9, 10]]) 42 a.shape = 2,-1 #当某个轴的元素为-1时,将根据数组元素的个数自动计算此轴的长度,因此下面的程序将数组c的 43 d = a.reshape((2,2)) #使用数组的reshape方法,可以创建一个改变了尺寸的新数组,原数组的shape保持不变. 44 #!!!但是数组a和d其实共享数据存储内存区域,因此修改其中任意一个数组的元素都会同时修改另外一个数组。
astype:astype转换数组对象的类型,会创建一个新的数组,相当于原始数据的复制
Numpy对象的属性
- ndims属性:用于返回秩,即数组的维数。
- shape属性:以 tuple表示的数组形狀,描述了数组对象各个维度的长度。
- size属性:用以查看数组元素总数。
- itemsize属性:以字节为单位,表示返回数组中每一个元素的大小。
- flags属性:表示返回的是对象的内存信息,比如ndarry数组的存储方式,以及是否是其它数组的副本等
与列表通过切片获取的新的数组是原始数组的一个复制,不能通过切片的返回结果来改变原有数组。
对切片表达式的赋值操作将会被扩散到整个选择对区域。
布尔型索引(很6)
通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
1 arr = np.arange(12) .reshape(4,3) 2 ##array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) 3 ##计算arr中大于5的数 4 print(arr>5) 5 ## [[False False False] [False False False] [ True True True] 6 ## [ True True True]] 7 print(arr[arr>5]) 8 ## [ 6 7 8 9 10 11] 9 ##计算arr中不等于5的数 10 print(arr[arr!=5]) 11 ## [ 0 1 2 3 4 6 7 8 9 10 11]
切片索引和花式索引
a = np.arange(9,1,-1) b = a[2:5] c = a[[1,5,3]] #一次传入多个索引数组,返回的将是一个一维数组。要想选取的矩阵行列的子集是矩形区域的形式,就要使用np.ix_函数,应用ix_函数实现箱卡儿积的映射关系。 arr = np.arange(32) .reshape(8,4) brr = arr[np.ix_([1,5,7,2],[0,3,1,2])] #np.ix_函数将数组[1,5,7,2]和数组[0,3,1,2] 产生笛卡儿积,得到如下数据: #(1,0),(1,3),(1,1),(1,2), #(9,0),(5,3),(5,1),(5,2), #(7,0),(7,3),(7,1),(7,2), #(2,0),(2,3),(2,1),(2,2)
内置函数
NumPy对象中常见函数有字符串函数、统计函数、数学函数、算数函数、排序及筛选函数等
字符串函数____numpy.char.函数名()
add()函数依次对两个数组的元素进行字符串连接
1 np.char.add(['hello'],['world']) 2 # array(['helloworld'], dtype='<U10') 3 np.char.add(['hello','ab'],['world','cd']) 4 # array(['helloworld', 'abcd'], dtype='<U10')
multiply()函数返回按元素多重连接后的字符串
center()函数可以将字符串居中,并使用指定字符填充在字符串两侧
1 np.char.multiply('Hi',5) 2 # array('HiHiHiHiHi', dtype='<U10') 3 np.char.center('Hi',10,fillchar='-') 4 # array('----Hi----', dtype='<U10')
capitalize()函数将字符串的第一个字母转换为大写
title()函数将字符串每个单词的第一个字母转换为大写
lower()函数将数组中的每个元素转换为小写
upper()函数将数组中的每个元素转换为大写
split()函数对字符串进行分隔并返回数组,可以指定分隔符进行分隔,默认情况下的分隔符为空格
splitlines()函数与split()相似,不同的是以换行符作为分隔符来分隔字符串,并返回数组,\n、\r、\r\n都可用作分隔符
strip()函数用于移除开头或结尾处的特定字符
join()函数通过指定分隔符来连接数组中的元素或字符串
replace()函数将使用新字符串替换原字符串中的所有子字符串
encode()函数对数组中的每个元素调用进行编码。默认为utf-8
decode()函数对编码的元素进行解码
1 print(np.char.capitalize('i love you')) 2 print(np.char.title('i love you')) 3 print(np.char.upper('i love you')) 4 ''' 5 I love you 6 I Love You 7 I LOVE YOU 8 ''' 9 print(np.char.strip('i love you','i')) 10 print(np.char.join(':','love')) 11 print(np.char.replace('aabbccdd','cc','pp')) 12 ''' 13 love you #这里空格还保留着 14 l:o:v:e 15 aabbppdd 16 ''' 17 arr = np.char.encode('love','cp500') 18 print(arr) 19 print(np.char.decode(arr,'cp500')) 20 ''' 21 b'\x93\x96\xa5\x85' 22 love 23 '''
统计函数
NumPy 有很多非常实用的统计函数,用于从数组给定的元素中按照指定轴查找平均数、最小值、最大值、百分标准差和方差等。
求和函数
sum()计算数组元素之和,也可以对列表、元组等和数组类似的序列进行求和。当数组是多维时,它计算数组中所有元素的和。
1 a =np.random.randint(0,10,size=(4,5)) 2 ''' 3 array([[7, 1, 9, 6, 3], 4 [5, 1, 3, 8, 2], 5 [9, 8, 9, 4, 0], 6 [9, 5, 1, 7, 0]]) 7 ''' 8 np.sum(a) 9 # 97
如果指定axis参数,求和运算将沿着指定的轴进行。在上面的例子中,数组a的第0轴(列)长度为4, 第1轴(行)长度为5。如果axis参数为1,就对每行上的5个数求和,所得的结
果是长度为 4的一维数组。如果参数axis为0,就对每列上的4个数求和,结果是长度为5的一维数组。 即结果数组的形状是原始数组的形状除去其第axis个元素。
1 np.sum(a,axis=1) 2 # array([26, 19, 30, 22]) 3 np.sum(a, axis=0) 4 # array([30, 15, 22, 25, 5])
- sum()默认使用和数组的元素类型相同的累加变量进行计算,如果元素类型为整数,就使 用系统的默认整数类型作为累加变量。
- 在32位系统中,累加变量的类型为32 bit整型。整数累加时,存在溢出问题,即数组元素的总和超过了累加变量的取值范围。
- 很大单精度浮点数类型累加时,存在精度不够的问题。可以通过dtype 参数指定累加变量的类型解决。
平均值
mean()用于求数组的平均值(期望),也可以通过axis参数指定求平均值的轴,通过out参数指定输出数组。和sum()不同的是,对于整数数组,它使用双精度浮点数进行计算。其他类型的数组,则使用和数组元素类型相同的累加变量进行计算。
1 np.mean(a,axis=1) #整数数组使用双精度浮点数进行计算 2 # array([ 5.2,3.8,6. , 4.4]) 3 np.mean(b) #单精度浮点数使用单精度浮点数进行计算 4 # 1.1109205 5 np.mean(b, dtype=np.double) #用双稍度浮点数计算平均值 6 # 1.1000000238418579
np.average(X, axis=0,weights=w)(加权平均值)也可以对数组进行平均计算。无out和dtype参数,但有一个指定每个元素权值的weights参数。
1 X = np.array([[.9, .1],[.8, .2],[.4, .6]]) 2 w = np.array([.2, .2, .6]) 3 print(w.dot(X)) 4 print(np.average(X, axis=0, weights=w))
最值
min()和max() 计算数组的最大值和最小值。
ptp()计算极差,即最大值和最小值之间的差。
它们都有axis和out两个参数。这些参数的用法和sum()相同。
argmax()和argmin()求最大值和最小值的下标。如果不指定axis参数,就返回平坦化之后的数组下标。
1 np.min(a2) 2 # 1.0 3 np.max(a2) 4 # 9.0 5 np.ptp(a2) 6 # 8.0 7 np.argmax(a) #找到数组a中最大值的下标,有多个最值时得到第一个最值的下标 8 # 2 9 a.ravel()[2] #求平坦化之后的数组中的第二个元素 10 # 9
axis参数表示沿着指定的轴计算最大值的下标。下面的结果表示,在数组 a中,第0行中最大值的下标为2,第1行中最大值的下标为3下面的语句,并使用idx选择出每行的最大值:
1 idx = np.argmax(a, axis=1) 2 # array([2, 3, 0, 0]) 3 a[xrange(a.shape[0]),idx] 4 # array([9, 8, 9, 9])
argsort()返回数组的排序下标,axis参数的默认值为-1。
1 idx = np.argsort(a) 2 ''' 3 array([[1, 4, 3, 0, 2], 4 [1, 4, 2, 0, 3], 5 [4, 3, 1, 0, 2], 6 [4, 2, 1, 3, 0]]) 7 '''
中位数
median()可以获得数组的中值,即对数组进行排序之后,位于数组中间位置的值。
当长度是偶数时,得到正中间两个数的平均值。它也可以指定axis和out参数。
方差
var()函数返回的是数组中元素的方差。
方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量,是衡量源数据和期望值相差的度量值,方差越大,离散程度越大。
标准差
std()函数返回的是数组中元素的标准差,又称均方差,是方差的算术平方根,标准差越大,离散程度越大。
百分位
percentile():百分位数是统计中使用的度量,表示小于这个值的观察值占某个百分比。
numpy.percentile(a, q, axis)
其中:a 输入数组;q 要计算的百分位数,在 0~100之间;axis 沿着它计算百分位数的轴。
数学函数
NumPy 包含大量的各种数学运算的函数,包括三角函数、算术运算的函数、复数处理函数等。
arcsin()、arccos()和arctan()函数是返回给定角度的sin(),cos()和 tan()的反三角函数。这些函数的结果可以通过 NumPy. degrees()函数将弧度转换为角度。
数字舍入函数包括around()、floor()、ceil()等函数,around()函数返回指定数字的四舍五入值n floor()函数返回小于或者等于指定值的最大整数,即向下取整。
ceil()函数与 floor()函数正相反,返回的是大于或者等于指定值的最小整数,即向上取整。
算术函数
NumPy 算术函数包含简单的加、减、乘、除,借助它们可以实现常见的算术运算。
需要注意的是:数组必须具有相同的形状或符合数组广播规则。
reciprocal 函数返回参数组元素的倒数。
power 函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。
mod 函数计算输入数组中相应元素相除后的余数,函数remainder ()也产生相同的结果。
排序
数组的sort()方法用于对数组进行排序,它将改变数组的内容。sort()函数则返回一个新数组,不改变原始数组。它们的axis参数默认值都为-1,即沿着数组的最后一个轴进行排序。sort()函数的axis参数可以设置为None,此时它将得到平坦化之后进行排序的新数组。
argsort()返回数组的排序下标,axis参数的默认值为-1。
lexsort()用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。
数组的运算
Python中提供了list容器,但为了保存一个简单的列表如[2,5,6],就需要三个指针和三个整数对象,这会使运算效率大大降低。
NumPy的出现弥补了这些不足,团为它使用户不需编写循环代码就可以对数据执行批量操作,一般称其为矢量化。
四则运算:对应位置元素加、减、乘、除。
广播
广播机制:numpy 在算术运算期间采用“广播”来处理具有不同形状的数组 。广播提供了一种矢量化的数组操作方法,使较小的数组在较大的数组上“广播”,以便它们具有兼容的形状。
广播规则:对两个数组进行操作时,numpy 会逐元素比较它们的形状。从尾(即最右边)维度开始,然后向左逐渐比较。只有当两个维度 相等 或者 其中一个维度是1 时,这两个维度才会被认为是兼容。
具体规则和步骤:
1、让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐。
2、输出数组的shape是输入数组shape的各个轴上的最大值。
3、如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错。
4、当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值。
基于数组的文件输入与输出
Numpy内置二进制格式,能够读或写磁盘上的文本数据或者二进制数据,但更多的用户会选择使用pandas或其他工具加载文本或表格数据。
np.save和np.load是读/写磁盘数组的两个主要函数。在默认情况下,数组是求以未压缩的原始二进制格式保存在扩展名为.npy的文件中,如果文件路径末尾没有扩展名.npy,则该扩展名会被自
动加上,然后就可以通过np.load 读取磁盘上的数组。
1 arr = np. arange (12) 2 np. save( 'a.array' ,arr) 3 np. load ( 'a_array. npy’ )
通过np.savez 可以将多个数组保存到一个未压缩文件中,将数组以关键字参数的形式传入即可。
加载.npz 文件时会得到一个类似字典的对象,该对象会对各个数组进行延迟加载。如果要将数据压缩,可以使用NumPy savez-compressed
1 np. savez('Numpy.npz',a = arr, b= arr) 2 arch=np.load('Numpy.npz') 3 np.savez_compressed('arrays_compressed.npz',a=arr,b=arr)
利用数组进行数据处理
-------------待补充,P102-----------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构