NumPy的常用方法
NumPy是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多。NumPy(Numeric Python)提供了许多高级的数值编程工具。NumPy的一个重要特征是它的数组计算,是我们做数据分析必不可少的一个包。导入Python的第三方库使用关键字import,后面可以自定义库的简称,但是一
NumPy是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多。
NumPy(Numeric Python)提供了许多高级的数值编程工具。NumPy的一个重要特征是它的数组计算,是我们做数据分析必不可少的一个包。
导入Python的第三方库使用关键字import,后面可以自定义库的简称,但是一般都将NumPy命名为np,pandas命名为pd。
使用前一定要先导入NumPy包,导入的方法有以下几种:
import numpy
import numpy as np
from numpy import * ##不用加包名的前缀,但和其他包函数重名容易报错,慎用!
NumPy的数组对象和简单数学运算:
值得注意的是:假如我们想将列表中的每个元素增加1以及两个列表相加时,列表不支持刚刚的操作:
a=[1,2,3,4]
[i+1 for i in a] #列表元素都加1
a=[1,2,3,4]
b=[2,3,4,5]
[x+y for (x,y) in zip(a,b)] #列表相加
这样的操作比较麻烦,而且在数据量特别大的时候会非常耗时间。如果我们使用Numpy,就会变得特别简单。
产生数组:
与列表不同,数组中要求所有元素的dtype是一样的,如果传入参数的类型与数组类型不一样,需要按照已有的类型进行转换。
使用特定的方法生成特殊的数组:
#生成整数序列:
a=np.arange(1,10,2) #左闭右开,默认步长是 1
#生成等差数列:
a=np.linspace(1,10,21) #linspace(起点,终点,个数),此处从1开始到10结束,生成21个元素,闭区间
np.random.rand(12) # [0,1)区间的12个随机数
np.random.randn(12) # 生成12个符合标准正态分布的随机数
c=np.random.randint(1,10,10) # 生成[1,10)间的10个随机整数
数组属性:
索引和切片:(和列表很相似,可以对比着理解)
#索引第一个元素
a=np.array([1,2,3,4])
a[0]
#修改第一个元素的值
a[0]=10
#切片,支持负索引,注意这是一个左闭右开的区间
a=np.array([11,12,13,14,15])
a[1:3]
a[1:-2]
#省略参数
a=np.array([11,12,13,14,15])
a[-2:]
a[::2] #和列表的基本相同,这个 2 是步长
#错位相减
b=np.array([11,25,46,58,76])
b1=b[1:]
b2=b[:-1]
b1-b2
多维数组及其属性:
#将以列表为元素的列表传入,最终得到的就是一个二维数组
>>> a=np.array([[1,2,3,4],[5,6,7,8]])
>>> a
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
#查看形状
>>> a.shape
(2, 4)
#查看总的元素个数
>>> a.size
8
#查看数组的维数
>>> a.ndim
2
#多维数组索引
#对于二维数组,可以传入两个数字来索引
>>> a[1,3] #逗号左边的是行索引,右边的列索引
8
#通过索引可以直接修改元素的值并保存
>>> a[1,3]=520
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 520]])
#检索一行的元素
>>> a[1]
array([ 5, 6, 7, 520])
#检索一列的元素
>>> a[:,1]
array([2, 6])
多维数组的切片: [lower:upper:step]
>>> a=np.array([[0,1,2,3,4,5],
[10,11,12,13,14,15],
[20,21,22,23,24,25],
[30,31,32,33,34,35],
[40,41,42,43,44,45],
[50,51,52,53,54,55]])
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
#第一行的第四和第五两个元素
>>> a[0,3:5]
array([3, 4]) #逗号左边是行索引,逗号右边是列索引
>>> a[4:,4:]
array([[44, 45],
[54, 55]])
>>> a[:,2]
array([ 2, 12, 22, 32, 42, 52])
#取出第三、五行的奇数列
>>> a[2::2,::2]
array([[20, 22, 24],
[40, 42, 44]])
切片在内存中使用的是引用机制
>>> a=np.array([0,1,2,3,4])
>>> b=a[2:4]
>>> b[0]=888
>>> a
array([ 0, 1, 888, 3, 4]) #可以发现数组a发生了改变
>>> list=[1,2,3,4,5]
>>> list1=list[2:4]
>>> list1[0]=10
>>> list
[1, 2, 3, 4, 5] #可以发现列表没有发生改变
引用机制意味着,python并没有为b分配新的空间来存储它的值,而是让b指向了a所分配的内存空间 ,因此,改变b的值也会改变a的值,但是这种现象在列表中不会出现。
这样的好处在于,对于很大的数据,不用大量复制多余的值,节约了空间;缺点在于,可能出现改变一个值而改变另一个值的情况。一个解决方法是使用copy()方法产生一个复制,这个复制中会申请新的内存。
#使用copy(),生成一个新的内存空间,
>>> a=np.array([0,1,2,3,4])
>>> b=a[2:4].copy()
>>> b[0]=888
>>> a
array([0, 1, 2, 3, 4])
#a的值没有改变,因为a和b的内存空间不在相同了
花式索引:
>>> a=np.array([[0,1,2,3,4,5],
[10,11,12,13,14,15],
[20,21,22,23,24,25],
[30,31,32,33,34,35],
[40,41,42,43,44,45],
[50,51,52,53,54,55]])
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
>>> a[(0,1,2,3,4),(1,2,3,4,5)] ##两个括号相对位置的数分别为行索引和列索引
array([ 1, 12, 23, 34, 45])
>>> a[-3:,0:6:2]
array([[30, 32, 34],
[40, 42, 44],
[50, 52, 54]])
#使用布尔数组进行索引
>>> mask=np.array([1,0,1,0,1,0],dtype=bool)
>>> a[-3:,mask]
array([[30, 32, 34],
[40, 42, 44],
[50, 52, 54]])
与切片不同,花式索引返回的是原对象的一个复制而不是引用,分配了新的内存空间
# “不完全”索引
>>> a=np.array([[0,1,2,3,4,5],
[10,11,12,13,14,15],
[20,21,22,23,24,25],
[30,31,32,33,34,35],
[40,41,42,43,44,45],
[50,51,52,53,54,55]])
>>> y=a[:3]
>>> y
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25]])
# 这时候也可以使用花式索引取出2,3,5行
>>> con=np.array([0,1,1,0,1,0],dtype=bool)
>>> a[con]
array([[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[40, 41, 42, 43, 44, 45]])
where语句: ;where(array) ;where函数会返回所有非零元素的索引
>>> a=np.array([0,12,5,20])
>>> a>10
#判断元素是否大于10
array([False, True, False, True])
#返回大于10的元素的索引值,返回值是一个元组
>>> np.where(a>10)
(array([1, 3], dtype=int64),)
#也可直接使用数组操作
>>> a[a>10]
array([12, 20])
>>> a[np.where(a>10)]
array([12, 20])
数组类型转换:
数组操作:
##电影名称
mv_name=['肖申克的救赎','控方证人','美丽人生','阿甘正传','霸王别姬','泰坦尼克号','辛德勒的名单','这个杀手不太冷','疯狂动物成','海豚湾']
##评分人数
mv_num=np.array([692795,42995,327855,580897,478523,157074,306904,662552,284652,159302])
##评分
mv_score=np.array([9.6,9.5,9.5,9.4,9.4,9.4,9.4,9.3,9.3,9.3])
##电影时长
mv_length=np.array([142,116,116,142,171,194,195,133,109,92])
#数组排序
>>> np.sort(mv_num) #sort()函数,未改动原来数组的内容
array([ 42995, 157074, 159302, 284652, 306904, 327855, 478523, 580897,
662552, 692795])
#argsort()函数返回从小到大的排列在数组中的索引位置
>>> order=np.argsort(mv_num)
>>> order
array([1, 5, 9, 8, 6, 2, 4, 3, 7, 0], dtype=int64)
>>> mv_name[order[0]] #最少评分人数的电影名称
'控方证人'
数学操作:
##求和,两种方式皆可以
np.sum(mv_num)
mv_num.sum()
##类似的还有
最大值 max()
最小值 min()
均值 mean()
标准差 std()
方差 var()
##相关系数矩阵 cov()
>>> np.cov(mv_length,mv_score)
array([[1.26288889e+03, 4.55555556e-01],
[4.55555556e-01, 9.88888889e-03]])
多维数组的操作:
>>> a=np.arange(6)
>>> a
array([0, 1, 2, 3, 4, 5])
##修改原数组成2行3列,这个方法改变了原来数组的值
>>> a.shape=2,3
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> a.shape
(2, 3)
##与之对应的方法是reshape,但它不会改变原来数组的值,而是返回一个新的数组
>>> a=np.arange(6)
>>> b=a.reshape(2,3)
>>> b
array([[0, 1, 2],
[3, 4, 5]])
>>> a
array([0, 1, 2, 3, 4, 5])
##转置,有两种方法,不会改变原来数组的值
>>> b
array([[0, 1, 2],
[3, 4, 5]])
>>> b.T
array([[0, 3],
[1, 4],
[2, 5]])
>>> b.transpose()
array([[0, 3],
[1, 4],
[2, 5]])
>>> b
array([[0, 1, 2],
[3, 4, 5]])
数组连接:
concatenate((a0,a1,...,an),axis=0),默认情况下axis=0代表往跨行(down),而axis=1代表跨列(across)使用0值表示沿着每一列或行标签索引值向下执行方法,使用1值表示沿着每一行或者列标签索引值横向执行对应的方法。注意:这些数组要用()包括到一个元组中去。除了给定的轴外,这些数组其他轴的长度必须是一样的。
>>> x=np.array([[0,1,2],[10,11,12]])
>>> y=np.array([[50,51,51],[60,61,62]])
>>> print(x.shape,y.shape)
(2, 3) (2, 3)
##默认沿着第一维进行连接
>>> z=np.concatenate((x,y),axis=0)
>>> z
array([[ 0, 1, 2],
[10, 11, 12],
[50, 51, 51],
[60, 61, 62]])
##沿着第二维进行连接
>>> z=np.concatenate((x,y),axis=1)
>>> z
array([[ 0, 1, 2, 50, 51, 51],
[10, 11, 12, 60, 61, 62]])
##注意到这里x和y的形状是一样的,还可以将它们连接成三维的数组,但是concatenate不提供这样的功能,可以这样操作:
>>> z=np.array((x,y))
>>> z
array([[[ 0, 1, 2],
[10, 11, 12]],
[[50, 51, 51],
[60, 61, 62]]])
事实上,NumPy还提供了分别对应以上三种情况的函数:
>>> np.vstack((x,y)) #纵向堆叠
array([[ 0, 1, 2],
[10, 11, 12],
[50, 51, 51],
[60, 61, 62]])
>>> np.hstack((x,y)) #横向堆叠
array([[ 0, 1, 2, 50, 51, 51],
[10, 11, 12, 60, 61, 62]])
>>> np.dstack((x,y)) #三维数组
array([[[ 0, 50],
[ 1, 51],
[ 2, 51]],
[[10, 60],
[11, 61],
[12, 62]]])
NumPy内置函数:
这里就列举了一小部分常用的内置函数,如果您想要了解更多,可以参考下面的网址,里面有较为详细的介绍。
https://blog.csdn.net/nihaoxiaocui/article/details/51992860
以上就是我总结的numpy的一些常用的方法,希望对您有所帮助,也希望大家可以给我点个赞,也算对我的鼓励了。当然,如果有不恰当的地方,欢迎指正批评!!!
如果你想要学习更深层次的内容,建议参考一下网址:
Everything is difficult until you know how to do it.😀
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)