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的一些常用的方法,希望对您有所帮助,也希望大家可以给我点个赞,也算对我的鼓励了。当然,如果有不恰当的地方,欢迎指正批评!!!

如果你想要学习更深层次的内容,建议参考一下网址:

https://www.runoob.com/numpy

 

Everything is difficult until you know how to do it.😀

 

 

 

 

 

 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐