好,继续。这篇争取能把Numpy这章做个了结。
一、元素级数组函数
顾名思义就是能够运用到数组元素的函数。这里可以看下这个表格:
看完的感觉是,记不住。。。好的,那就看几个例子,其他的有个印象,需要的时候能够在文档中查到就行了。
arr = np.arange(10)
np.sqrt(arr) #平方根函数
输出:array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
np.exp(arr) #计算指数
输出:array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
2.98095799e+03, 8.10308393e+03])
x = randn(8)
y = randn(8)
x
输出:array([-0.27357369, 0.07827272, 1.2756936 , 0.06018418, 0.20406572,
-1.5830942 , -1.49025786, 0.20409636])
y
输出:array([ 1.28998788, 1.94645189, 0.13716615, -0.70732559, -0.32622699,
0.07944005, -0.71163361, 1.12823112])
np.maximum(x, y) #返回元素级最大值
输出:array([ 1.28998788, 1.94645189, 1.2756936 , 0.06018418, 0.20406572,
0.07944005, -0.71163361, 1.12823112])
二、利用数组进行数据处理
1、计算sqrt(x^2 + y^2)
step1: 利用np.meshgrid函数,接受两个一维数组,将其转化为两个二维数组。具体怎么转化的,真的难以描述,请看例子。转化的结果就是,xs成为1000组在x轴分布的数据,ys成为1000组在y轴分布的数据。
points = np.arange(-5, 5, 0.01) #生成一个数组,包含1000个数据,从-5到4.99,以0.01为阶差
xs, ys = np.meshgrid(points, points)
xs
输出:array([[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],
[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],
[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],
...,
[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],
[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99],
[-5. , -4.99, -4.98, ..., 4.97, 4.98, 4.99]])
ys
输出:array([[-5. , -5. , -5. , ..., -5. , -5. , -5. ],
[-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],
[-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],
...,
[ 4.97, 4.97, 4.97, ..., 4.97, 4.97, 4.97],
[ 4.98, 4.98, 4.98, ..., 4.98, 4.98, 4.98],
[ 4.99, 4.99, 4.99, ..., 4.99, 4.99, 4.99]])
step2:既然有了在x轴和y轴分别分布的数组,可以直接用于计算sqrt(x^2 + y^2)。这里还需要理解一下,比如我们看xs[0,0]是-5,ys[0,0]是-5,那么z[0, 0]就应该是sqrt((-5)^2 + (-5)^2)=7.07,这样就得到了z在x=-5,y=-5时的值。以此类推,就可以填充整个x=[-5,5),y=[-5,5)的全部网格区间。而因为xs、ys都是ndarray类型,所以直接对xs,ys计算sqrt(xs2+ys2),便可以得到z在整个网格区间的取值数组(同样是二维的)。
import matplotlib.pyplot as plt
z = np.sqrt(xs ** 2 + ys ** 2)
z
输出:array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,
7.06400028],
[7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
7.05692568],
[7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
7.04985815],
...,
[7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,
7.04279774],
[7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
7.04985815],
[7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
7.05692568]])
可以看到跟我们手动计算的z[0,0]的值是对应的上的。
step3:画出来
plt.imshow(z, cmap = plt.cm.gray); plt.colorbar()
输出:
这样我们就画出了z = sqrt(x^2 + y^2)函数。
2、将条件逻辑表述为数组运算
这一节主要讲解了np.where函数的用法。这是x if condition else y的矢量化版本,所谓矢量化就是对多维数组中的多组数据进行同样的运算。
step1:最基础用法
np.where的最基础用法就是np.where(condition,x,y),也就是接收一个布尔型数组和两个数组或标量然后返回一个处理后的数组。看例子:
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = np.where(cond, xarr, yarr)
result
输出:array([1.1, 2.2, 1.3, 1.4, 2.5])
arr = randn(4, 4)
arr
输出:array([[-1.0795204 , -0.20221883, 1.30506565, 0.9527885 ],
[ 1.35222978, 0.0041883 , 1.26632574, -1.43131923],
[-0.70823746, 0.41692397, 0.24624955, -0.19936078],
[-1.04796012, 0.63649599, 0.24446832, -2.34066063]])
np.where(arr>0, 2, -2) #把大于0的值转化成2,小于0的值转化成-2
输出:array([[-2, -2, 2, 2],
[ 2, 2, 2, -2],
[-2, 2, 2, -2],
[-2, 2, 2, -2]])
np.where(arr>0, 2, arr)
输出:array([[-1.0795204 , -0.20221883, 2. , 2. ],
[ 2. , 2. , 2. , -1.43131923],
[-0.70823746, 2. , 2. , -0.19936078],
[-1.04796012, 2. , 2. , -2.34066063]])
step2:嵌套用法
np.where支持嵌套用法
比如下面这段语句:
np.where(cond1 & cond2, 0, np.where(cond1, 1, np.where(cond2, 2, 3)))
就非常简单的完成了一段比较复杂的逻辑:当cond1&cond2成立,返回0,否则当cond1成立时返回1,否则当cond2成立时返回2,都不成立时返回3。
3、一些统计类的函数
先来看看基本统计方法有哪些。
以sum和mean为例,看下如何应用。
step1:基本用法,对整个数组求均值或和。
arr = randn(5, 4) #生成一个5*4的正态分布二维数组
arr.mean()
输出:-0.37234506116897803
arr.sum()
输出:-7.446901223379561
step2:针对某个轴求均值或和
arr.mean(axis = 1) #对y轴求均值
输出:array([-0.58997622, -0.35377743, -0.96737807, 0.10730068, -0.05789426])
arr.mean(0) #对x轴求均值,“axis =”可以省略
输出:array([-1.26302012, -0.16285536, 0.66826505, -0.73176982])
arr.mean(2) #超过数组维度,会报错。
arr.sum(axis = 0)
输出:array([-6.31510061, -0.81427678, 3.34132526, -3.6588491 ])
4、布尔型数组运算
(1)bool型数组的True值将被统计称1,False值将被统计成0
arr = randn(100)
(arr > 0).sum()
输出:48
(2)any和all函数
bools = np.array([True, False, False, False])
bools.any() #数组中是否有True
输出:True
bools.all() #数组中是否全都是True
输出:False
5、排序
sort函数
(1)基础用法
np.sort(ndarray):返回数组的排序副本,不改变原数组的数据顺序
或者
ndarray.sort():改变数组的数据顺序
arr = randn(8)
arr
输出:array([-0.60102707, 0.95990063, 0.63694133, -0.57739665, -0.29303645,
0.40691574, 0.55154861, 0.18252723])
np.sort(arr)
输出:array([-0.60102707, -0.57739665, -0.29303645, 0.18252723, 0.40691574,
0.55154861, 0.63694133, 0.95990063])
arr
输出:array([-0.60102707, 0.95990063, 0.63694133, -0.57739665, -0.29303645,
0.40691574, 0.55154861, 0.18252723])
arr.sort()
arr
输出:array([-0.60102707, -0.57739665, -0.29303645, 0.18252723, 0.40691574,
0.55154861, 0.63694133, 0.95990063])
(2)多维数组可以指定坐标轴对特定坐标轴上的数据排序
arr = randn(5, 3)
arr
输出:array([[-0.04902715, 0.21670487, 0.79632149],
[-1.5918878 , 0.7074961 , -0.69239241],
[ 0.17439338, -0.41831516, -0.14742609],
[ 0.86968645, -0.88234194, 0.08772758],
[ 0.41395088, -0.05980005, 0.07182037]])
arr.sort(1)
arr
输出:array([[-0.04902715, 0.21670487, 0.79632149],
[-1.5918878 , -0.69239241, 0.7074961 ],
[-0.41831516, -0.14742609, 0.17439338],
[-0.88234194, 0.08772758, 0.86968645],
[-0.05980005, 0.07182037, 0.41395088]])
(3)分位数算法
large_arr = randn(1000)
large_arr.sort()
large_arr[int(0.05 * len(large_arr))] #5%分位数
输出:-1.5379812661650785
好的,本篇依旧没能把numpy这章做个了结,还有线性代数以及随机数两部分(关于文件存取书中会有专门章节介绍,此处先略过)。下篇继续。