https://www.runoob.com/numpy
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 * ##不用加前缀,但和其他包函数重名容易报错
假如我们想将列表中的每个元素增加1,但列表不支持这样的操作:
a=[1,2,3,4]
a+1
结果:报错
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_12364\2382243670.py in <module>
1 a=[1,2,3,4]
----> 2 a+1
TypeError: can only concatenate list (not "int") to list
只能这样操作
a=[1,2,3,4]
[i+1 for i in a]
输出
[2, 3, 4, 5]
与另一个数组相加,得到对应元素相加的结果:
a=[1,2,3,4]
b=[2,3,4,5]
a+b
输出
[1, 2, 3, 4, 2, 3, 4, 5]
只能这样操作
a=[1,2,3,4]
b=[2,3,4,5]
[x+y for (x,y) in zip(a,b)]
输出
[3, 5, 7, 9]
这样的操作比较麻烦,而且在数据量特别大的时候会非常耗时间。
如果我们使用Numpy,就会变得特别简单
a=np.array([1,2,3,4])
b=np.array([2,3,4,5])
a+1
输出
array([2, 3, 4, 5])
----------------------------------------
a+b
输出
array([3, 5, 7, 9])
从列表产生数据
l=[0,1,2,3]
a=np.array(l)
a
输出
array([0, 1, 2, 3])
从列表传入
a=np.array([1,2,3,4])
a
输出
array([1, 2, 3, 4])
生成全0数组
a=np.zeros(5)
a
输出
array([0., 0., 0., 0., 0.])
生成全1数组
np.ones(5)
输出
array([1., 1., 1., 1., 1.]) ## 默认浮点数
--------------------------
加入dtype指定数据类型
------------------------------------
a=np.ones(5,dtype='int')
a
输出
array([1, 1, 1, 1, 1])
------------------------------------
a=np.ones(5,dtype='bool') ##dtype定义需要的数据类型
a
输出
array([ True, True, True, True, True])
可以使用fill方法将数组设定为指定值
与列表不同,数组中要求所有元素的dtype是一样的,如果传入参数的类型与数组类型不一样,需要按照已有的类型进行转换。
a=np.array([1,2,3,4])
a.fill(5)
a
输出
array([5, 5, 5, 5])
--------------------------------------
a.fill(2.5) ##传入的参数类型会按照原数组类型进行转换
a
输出
array([2, 2, 2, 2])
------------------------------------------
##使用fill方法将原数组类型改变
a=np.array([1,2,3,4])
a=a.astype('float')
a.fill(2.5)
a
输出
array([2.5, 2.5, 2.5, 2.5])
使用特定的方法生成特殊的数组
生成整数序列 arange
a=np.arange(1,10,2) ##arange(起点,终点,步长),左闭右开
a
输出
array([1, 3, 5, 7, 9])
生成等差数列 linspace
a=np.linspace(1,19,10) ##linspace(起点,终点,个数),此处从1开始到19结束,生成10个元素
a
输出
array([ 1., 3., 5., 7., 9., 11., 13., 15., 17., 19.])
生成随机数 random.rand/randn
a=np.random.rand(10) ##生成0-1的10个随机数(范围是0~1不包括1)
a
输出
array([0.17321107, 0.99373562, 0.3975442 , 0.70928465, 0.94911133,
0.42808941, 0.63640154, 0.79841176, 0.13196705, 0.94727648])
--------------------------------------------
b=np.random.randn(10) ##生成0-1的10个随机数,随机数服从标准正太分布
b
输出
array([-0.08383046, 0.63174363, 2.39860083, 0.38896599, 2.15220553,
-0.07221372, -0.05394666, -1.37264763, 1.48804014, 1.22077146])
-----------------------------------------------
c=np.random.randint(1,10,10) ##生成1-10的10个随机整数
c
输出
array([2, 7, 6, 8, 2, 5, 6, 3, 8, 3])
查看类型
a=np.array([1,2,3,4])
type(a)
输出
numpy.ndarray
查看数组中的数据类型
a.dtype
输出
dtype('int32')
查看形状,会返回一个元组,每个元素代表这一堆的元素数目
a.shape
输出
(4,)
查看数组里面元素的数目
a.size
4
查看数组的维度
a.ndim
1
索引第一个元素
a=np.array([1,2,3,4])
a[0]
1
修改第一个元素的值
a[0]=10
a
array([10, 2, 3, 4])
切片,支持负索引
a=np.array([11,12,13,14,15])
a[1:3]
输出
array([12, 13])
------------------------------------
a[1:-2]
输出
array([12, 13])
省略参数
a=np.array([11,12,13,14,15])
a[-2:]
输出
---------------------------------
array([14, 15])
a[::2]
输出
array([11, 13, 15])
错位相减
b=np.array([11,25,46,58,76])
b1=b[1:]
b2=b[:-1]
b1-b2
输出
array([14, 21, 12, 18])
将以列表为元素的列表传入,最终得到的额就是一个二维数组
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)
## (行数,列数)
查看总的元素个数
[64]:
a.size
8
查看维数
a.ndim
2
对于二维数组,可以传入两个数字来索引
[67]:
a=np.array([[1,2,3,4],[5,6,7,8]])
a
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
a[1,3] ## 索引从零开始,所以此处是1行3列
8
索引赋值
a[1,3]=9
a
array([[1, 2, 3, 4],
[5, 6, 7, 9]])
索引一整行内容
a[1]
array([5, 6, 7, 9])
Python会将这单个元组当成对第一堆的索引,然后返回对应的内容
行索引在逗号前,列索引在逗号后
a[:,1] ##返回的是第二列。
array([2, 6])
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]])
取到第一行的第4和第5两个元素
a[0,3:5]
array([3, 4])
得到最后两行的最后两列
a[4:,4:] ## [行切片,列切片]
array([[44, 45],
[54, 55]])
得到第3列
a[:,2]
array([ 2, 12, 22, 32, 42, 52])
每一堆都支持切片的规则,包括负索引,省略
[lower:upper:step]
[79]:
#例如:取出3,5行的奇数列
a[2:5:2,::2]
[79]:
array([[20, 22, 24],
[40, 42, 44]])
切片在内存中使用的是引用机制。
引用机制意味着,Python并没有为b分配新的空间来存储它的值,而实让b指向了a所分配的内存空间,因此,改变b会改变a的值。
a=np.array([0,1,2,3,4])
b=a[2:4]
b
输出
array([2, 3])
----------------------
b[0]=10 ## 改变b的0索引的值
a
输出
array([ 0, 1, 10, 3, 4])
而这种现象在列表中并不会出现
list=[1,2,3,4,5]
list1=list[2:4]
list1
输出
[3, 4]
-----------------------
list1[0]=10
list
输出
[1, 2, 3, 4, 5]
这样的好处在于,对于很大的数据,不用大量复制多余的值,节约了空间
缺点在于,可能出现改变一个值而改变另一个值的情况。
一个解决方法是使用copy()方法产生一个复制,这个复制中会申请新的内存。
a=np.array([0,1,2,3,4])
b=a[2:4].copy()
b[0]=10
a
输出
array([0, 1, 2, 3, 4])
切片只能支撑连续或者等间隔的切片操作,要想实现任意位置的操作,需要使用花式索引 fancy slicing
与range函数类似,我们可以使用arange函数来产生等差数组
a=np.arange(0,100,10)
a
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
花式索引需要指定索引位置
index=[1,2,-3]
y=a[index]
y
输出
array([10, 20, 70])
还可以使用布尔数组来花式索引
mask=np.array([0,2,2,0,0,1,0,0,1,0],dtype=bool) ## 长度需要与要索引的数组长度一致
mask
输出
array([False, True, True, False, False, True, False, False, True,
False])
-------------------------
y=a[mask]
y
输出
array([10, 20, 50, 80])
mask必须是布尔数组,长度必须和数组长度相等
对于二维花式索引,我们需要给定行和列的值
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]])
返回的是一条次对角线上的5个值(此处取1,12,23,34,45)
a[(0,1,2,3,4),(1,2,3,4,5)] ##两个括号相对位置的数分别为行标和列标
输出
array([ 1, 12, 23, 34, 45])
返回最后三行的1,3,5列
a[-3:,0:6:2]
array([[30, 32, 34],
[40, 42, 44],
[50, 52, 54]])
a[-3:,[0,2,4]]或者a[3:,(0,2,4)]
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]])
mask=np.array([1,0,1,0,1,0],dtype=bool) ## 行索引
a[mask,2]
输出
array([ 2, 22, 42])
与切片不同,花式索引返回的是对象的一个复制而不是引用
只给定行索引的时候,返回整行
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(array)
where函数会返回所有非零元素的索引
a=np.array([0,12,5,20])
判断句数组中的元素是不是大于10
a>10
array([False, True, False, True])
数组中所有大于10的元素的索引位置
np.where(a>10)
(array([1, 3], dtype=int64),)
注意到where的返回值是一个元组,返回的是索引位置
也可以直接用数组操作
a[a>10]
array([12, 20])
a[np.where(a>10)]
array([12, 20])
a=np.array([1.5,-3],dtype=int)
a
array([ 1, -3])
asarray函数
a=np.array([1,2,3])
np.asarray(a,dtype=float) ## 原数组不变
array([1., 2., 3.])
astype函数
##astype方法返回一个新数组
a=np.array([1,2,3])
a.astype(float) ### a=np.array([1,2,3],dtype='float')
array([1., 2., 3.])
a=np.array([1,2,3])
b=a.astype(float)
b[0]=0.5
b
array([0.5, 2. , 3. ])
a
array([1, 2, 3])
astype引用不会对原数组产生影响
以豆瓣10部高分电影为例
##电影名称
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])
sort函数
##对评分人数排序
np.sort(mv_num)
结果
array([ 42995, 157074, 159302, 284652, 306904, 327855, 478523, 580897,
662552, 692795])
mv_num ##sort函数不改变原数组
结果
array([692795, 42995, 327855, 580897, 478523, 157074, 306904, 662552,
284652, 159302])
argsort函数
argsort返回从小到大的排列在数组中的索引位置
order=np.argsort(mv_num)
order
array([1, 5, 9, 8, 6, 2, 4, 3, 7, 0], dtype=int64)
##看评分人数最少
order[0]
结果
1
##通过order获得索引,然后查看对应索引的其他数组信息
mv_name[1]
'控方证人'
求和
np.sum(mv_num)
结果
3693549
------------------------
mv_num.sum()
结果
3693549
--------------------------------
mv_length.max()
结果
195
-----------------------------------
np.max(mv_length)
结果
195
最小值 min(同sum)
均值 mean(同sum)
标准差 std(同sum)
方差 var(同sum)
相关系数矩阵 cov
np.cov(mv_score,mv_length) ## 电影评分和电影时长的相关系数
结果
array([[9.88888889e-03, 4.55555556e-01],
[4.55555556e-01, 1.26288889e+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)
a
结果
array([0, 1, 2, 3, 4, 5])
a.reshape(2,3)
结果
array([[0, 1, 2],
[3, 4, 5]])
a
结果
array([0, 1, 2, 3, 4, 5])
a=a.reshape(2,3)
a
结果
array([[0, 1, 2],
[3, 4, 5]])
a.T
结果
array([[0, 3],
[1, 4],
[2, 5]])
a.transpose()
结果
array([[0, 3],
[1, 4],
[2, 5]])
a
结果
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=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提供了分别对应这三种情况的函数
vstack
np.vstack((x,y))
结果
array([[ 0, 1, 2],
[10, 11, 12],
[50, 51, 51],
[60, 61, 62]])
hstack
np.hstack((x,y))
结果
array([[ 0, 1, 2, 50, 51, 51],
[10, 11, 12, 60, 61, 62]])
dstack
np.dstack((x,y))
结果
array([[[ 0, 50],
[ 1, 51],
[ 2, 51]],
[[10, 60],
[11, 61],
[12, 62]]])
https://www.runoob.com/numpy/numpy-string-functions.html
a=np.array([-1,2,3,-2])
##绝对值
np.abs(a)
结果
array([1, 2, 3, 2])
##指数
np.exp(a)
结果
array([ 0.36787944, 7.3890561 , 20.08553692, 0.13533528])
##中值
np.median(a)
结果
0.5
##累计和(从前到后依次累加)
np.cumsum(a)
结果
array([-1, 1, 4, 2], dtype=int32)
还有很多,可以查资料了解