【Task04】Numpy学习打卡

Task04学习思维导图

在这里插入图片描述

注:为了节约行数,默认import numpy as np已经写在每段代码前,不再重复写入,如果有新的包引入,会在代码头部import。

十、向量化和广播

1.向量化

我们先看一个numpy中向量化的例子:

【十、例1-1】numpy向量化之加法

>>> a = np.arange(1,5)
>>> b = np.arange(1,5)
>>> print(a,b,a+b)
[1 2 3 4] [1 2 3 4] [2 4 6 8]
>>> print([a[i]+b[i] for i in range(4)])
[2, 4, 6, 8]
>>> c = [x for x in range(1,5)]
>>> d = [x for x in range(1,5)]
>>> print(c,d,c+d)
[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 1, 2, 3, 4]
>>> print([c[i]+d[i] for i in range(4)])
[2, 4, 6, 8]

我们可以看到a+b返回的是a和b内元素分别相加之后再组合起来的结果,相比下python原生中c+d代表两个list直接相加。

更多地,numpy还有其他关于向量化的用法,如:

【十、例1-2】numpy向量化举例其他

>>> a = np.arange(1,5)
>>> b = np.arange(1,5)
#其他运算
>>> print(a-b)
>>> print(a*b)
>>> print(a/b)
>>> print(a**b)
[0 0 0 0]
[ 1  4  9 16]
[1. 1. 1. 1.]
[  1   4  27 256]
#乘以标量
>>> print(a*3)
[ 3  6  9 12]
#与、或、补码
>>> print(a&b)
[1 2 3 4]
#短路 a若为True跳过后面
>>> print(a|b)
[1 2 3 4]
>>> print(~a)
[-2 -3 -4 -5]
>>> print(a&True)
[1 0 1 0]
>>> print(a&False)
[0 0 0 0]
#比较
>>> print(a > np.e)
>>> print(a >= np.e)
>>> print(a < np.e)
>>> print(a <= np.e)
>>> print(a == np.e)
>>> print(a != np.e)
[False False  True  True]
[ True  True False False]
[ True  True False False]
[False False False False]
[ True  True  True  True]
#索引数组 布尔切片
>>> print(a[a < 3])
[1 2]
# +=与+的区别
>>> c = np.arange(1,5)
>>> d = c
>>> c += c
>>> print(d)
[2 4 6 8]
>>> c = np.arange(1,5)
>>> d = c
>>> c = c+c
>>> print(d)
[1 2 3 4]

这里重点说一下+=与+的区别,c += c改变了原地址的值,而c=c+c只改变了c的引用,并没有改变原来的值,因为后者在c+c时,返回的地址就已经不是原来的地址了。

2.广播

当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。

广播的规则:

  • 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
  • 输出数组的形状是输入数组形状的各个维度上的最大值。
  • 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
  • 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。

【十、例2-1】numpy广播实例

# 4,和4,4运算
a = np.arange(4)
print(a,a.shape)
[0 1 2 3] (4,)
b = np.zeros([4,4])
print(b)
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
print(a+b)
[[0. 1. 2. 3.]
 [0. 1. 2. 3.]
 [0. 1. 2. 3.]
 [0. 1. 2. 3.]]

# 4,和4,1运算
a = np.arange(4)
print(a)
[0 1 2 3]
b = np.zeros([4,1])
print(b)
[[0.]
 [0.]
 [0.]
 [0.]]
print(a+b)
[[0. 1. 2. 3.]
 [0. 1. 2. 3.]
 [0. 1. 2. 3.]
 [0. 1. 2. 3.]]

#3,和4,运算
a = np.arange(3)
print(a)
b = np.arange(4)
print(b)
print(a+b)
ValueError: operands could not be broadcast together with shapes (3,) (4,) 

简单概括就是,如果shape不匹配,要么其中一个是1,要么可以补维度,需要满足下面的情况:

在这里插入图片描述
否则就会报错。

十一、数学函数

前言

不把广播效应算在内,本章的内容很少会改变原始数据本身的shape,所以着重点在于弄明白每个数学函数的使用方法。

1.算数运算

算数运算函数主要有:

  • add():加
  • subtract():减
  • multiply():乘
  • divide():除
  • floor_divide():整除
  • power():a的b次幂
  • sqrt():开根号
  • square():a的平方

举例说明它们的用法:

【十一、例1】算数运算函数实例

>>> a = np.random.randint(1,10,[3,3])
>>> print(a)
[[7 7 2]
 [6 6 7]
 [9 5 7]]
>>> b = np.random.randint(1,10,3)
>>> print(b)
[7 3 7]
#加
>>> print(np.add(a,b))
[[14 10  9]
 [13  9 14]
 [16  8 14]]
#减
>>> print(np.subtract(a,b))
[[ 0  4 -5]
 [-1  3  0]
 [ 2  2  0]]
#乘
>>> print(np.multiply(a,b))
[[49 21 14]
 [42 18 49]
 [63 15 49]]
#除
>>> print(np.divide(a,b))
[[1.         2.33333333 0.28571429]
 [0.85714286 2.         1.        ]
 [1.28571429 1.66666667 1.        ]]
#整除
>>> print(np.floor_divide(a,b))
[[1 2 0]
 [0 2 1]
 [1 1 1]]
#a的b次幂
>>> print(np.power(a,b))
[[ 823543     343     128]
 [ 279936     216  823543]
 [4782969     125  823543]]
#根
>>> print(np.sqrt(a))
[[2.64575131 2.64575131 1.41421356]
 [2.44948974 2.44948974 2.64575131]
 [3.         2.23606798 2.64575131]]
#平方
>>> print(np.square(a))
[[49 49  4]
 [36 36 49]
 [81 25 49]]

2.三角函数

三角函数主要有:

  • sin():正弦
  • cos():余弦
  • tan():正切
  • arcsin():反正弦
  • arccos():反余弦
  • arctan():反正切

以及numpy.degrees()是用来将弧度转为角度,举例说明它们的使用方法:

【十一、例2】三角函数实例

>>> import matplotlib.pyplot as plt
>>> a = np.linspace(0,2 * np.pi,20)
>>> b = np.sin(a)
>>> print(b)
[ 0.00000000e+00  3.24699469e-01  6.14212713e-01  8.37166478e-01
  9.69400266e-01  9.96584493e-01  9.15773327e-01  7.35723911e-01
  4.75947393e-01  1.64594590e-01 -1.64594590e-01 -4.75947393e-01
 -7.35723911e-01 -9.15773327e-01 -9.96584493e-01 -9.69400266e-01
 -8.37166478e-01 -6.14212713e-01 -3.24699469e-01 -2.44929360e-16]
>>> plt.plot(a,b)

在这里插入图片描述

>>> b = np.cos(a)
>>> plt.plot(a,b)

在这里插入图片描述

>>> a = np.linspace(-0.49*np.pi,0.49*np.pi,100)
>>> b = np.tan(a)
>>> plt.plot(a,b)

在这里插入图片描述
这里注意tan()的范围在(-pi/2,pi/2)之间,所以我们有0.49*pi来限定范围。

3.指数和对数

直接上例子说明:

【十一、例3】指数和对数函数实例

>>> a = np.random.randint(1,10,5)
>>> print(a)
[6 5 4 6 3]
#exp e的x次方
>>> print(np.exp(a))
[403.42879349 148.4131591   54.59815003 403.42879349  20.08553692]
#log 以e为底x的对数
>>> print(np.log(a))
[1.79175947 1.60943791 1.38629436 1.79175947 1.09861229]
#log2 以2为底x的对数
>>> print(np.log2(a))
[2.5849625  2.32192809 2.         2.5849625  1.5849625 ]
#log10 以10为底x的对数
>>> print(np.log10(a))
[0.77815125 0.69897    0.60205999 0.77815125 0.47712125]
#exp2 2的x次方
>>> print(np.exp2(a))
[64. 32. 16. 64.  8.]

这里容易混淆的是np.exp2(),因为np.exp()是e的x次方,所以容易把前者跟e联系起来,要注意。

4.加法函数和乘法函数

直接上例子说明:

【十一、例4】加法函数和乘法函数实例

>>> a = np.random.randint(1,10,[4,4])
>>> print(a)
[[2 6 1 9]
 [8 5 2 5]
 [7 6 2 2]
 [5 2 4 2]]
#整和
>>> print(np.sum(a))
68
#沿行求和(列和)
>>> print(np.sum(a,axis=0))
[22 19  9 18]
#沿列求和(行和)
>>> print(np.sum(a,axis=1))
[18 20 17 13]
#累积和(扁平化后)
>>> print(np.cumsum(a))
[ 2  8  9 18 26 31 33 38 45 51 53 55 60 62 66 68]
#沿行求累积和(列累积和)
>>> print(np.cumsum(a,axis=0))
[[ 2  6  1  9]
 [10 11  3 14]
 [17 17  5 16]
 [22 19  9 18]]
#沿列求累积和(行累积和)
>>> print(np.cumsum(a,axis=1))
[[ 2  8  9 18]
 [ 8 13 15 20]
 [ 7 13 15 17]
 [ 5  7 11 13]]
#整积
>>> print(np.prod(a))
580608000
#沿行求积(列积)
>>> print(np.prod(a,axis=0))
[560 360  16 180]
#沿列求积(行积)
>>> print(np.prod(a,axis=1))
[108 400 168  80]
#累积(扁平化后)
>>> print(np.cumprod(a))
[        2        12        12       108       864      4320      8640
     43200    302400   1814400   3628800   7257600  36288000  72576000
 290304000 580608000]
#沿行求累积(列累积)
>>> print(np.cumprod(a,axis=0))
[[  2   6   1   9]
 [ 16  30   2  45]
 [112 180   4  90]
 [560 360  16 180]]
#沿列求累积(行累积)
>>> print(np.cumprod(a,axis=1))
[[  2  12  12 108]
 [  8  40  80 400]
 [  7  42  84 168]
 [  5  10  40  80]]
#沿列求差(相邻行之差)
>>> print(np.diff(a))
[[ 4 -5  8]
 [-3 -3  3]
 [-1 -4  0]
 [-3  2 -2]]
#沿行求差(相邻列之差)
>>> print(np.diff(a,axis=0))
[[ 6 -1  1 -4]
 [-1  1  0 -3]
 [-2 -4  2  0]]

注:上述所有的axis=0其实是沿着行去遍历,但求的是列之间的关系,比如sum中求的是列和,同理axis=1其实是沿着列去遍历,是在求行之间的关系。

5.四舍五入函数

直接上例子说明:

【十一、例5】四舍五入函数实例

>>> a = np.random.rand(3,3)*10
>>> print(a)
[[1.16944655 7.50128062 2.21134653]
 [8.33939104 9.46452031 4.58700646]
 [5.15796925 4.75485535 6.39179018]]
#四舍五入
>>> print(np.around(a))
[[1. 8. 2.]
 [8. 9. 5.]
 [5. 5. 6.]]
#向上取整
>>> print(np.ceil(a))
[[ 2.  8.  3.]
 [ 9. 10.  5.]
 [ 6.  5.  7.]]
#向下取整
>>> print(np.floor(a))
[[1. 7. 2.]
 [8. 9. 4.]
 [5. 4. 6.]]

6.统计函数

NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等。包括:

  • amin():沿指定轴的最小值
  • amax():沿指定轴的最大值
  • ptp():沿指定轴的最小值与最大值之差
  • percentile():统计中使用的度量
  • median():计算数组 a 中元素的中位数
  • mean():返回数组中元素的算术平均值
  • average():根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值
  • std():标准差
  • var():方差

【十一、例6-1】一般统计函数实例

>>> a = np.random.randint(1,10,[5,5])
>>> print(a)
[[2 8 3 2 6]
 [6 8 7 4 8]
 [2 3 7 9 4]
 [1 2 1 9 7]
 [9 7 3 6 2]]
#沿第一维度的最小值
>>> print(np.amin(a,axis=0))
[1 2 1 2 2]
#沿第一维度的最大值
>>> print(np.amax(a,axis=0))
[9 8 7 9 8]
#沿第一维度的最小值与最大值之差
>>> print(np.ptp(a,axis=0))
[8 6 6 7 6]
#沿第一维度中位数
>>> print(np.median(a,axis=0))
[2. 7. 3. 6. 6.]
#沿第一维度算术平均值
>>> print(np.mean(a,axis=0))
[4.  5.6 4.2 6.  5.4]
#沿第一维度标准差
>>> print(np.std(a,axis=0))
[3.03315018 2.57681975 2.4        2.75680975 2.15406592]
#沿第一维度方差
>>> print(np.var(a,axis=0))
[9.2  6.64 5.76 7.6  4.64]

这里重点讲一下percentile()average():

在这里插入图片描述在这里插入图片描述

百分位数是统计中使用的度量,表示小于这个值的观察值的百分比,举例说明:

【十一、例6-2】percentile()函数实例

>>> a = np.array([[10, 7, 4], [3, 2, 1]])
>>> print(a)
[[10  7  4]
 [ 3  2  1]]
>>> print(np.percentile(a, 50))
3.5
>>> print(np.percentile(a, 70))
5.5
>>> print(np.percentile(a, 50, axis=0))
[6.5 4.5 2.5]
>>> print(np.percentile(a, 50, axis=1))
[7. 2.]
>>> print(np.percentile(a, 50, axis=1, keepdims=True))
[[7.]
 [2.]]

我们以np.percentile(a, 70)为例,探究其计算方式:

  1. (数组长度-1)* 百分比 = (6-1) * 70% = 3.5 = a+b
  2. a = 3,b = 0.5
  3. result = (1 - b)× arr[a] + b x arr[a+1] = 0.5 * 4 + 0.5 + 7 = 5.5

即为所求。

numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。

该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。

加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。

【十一、例6-3】average()函数实例

# 不指定权重时相当于 mean 函数
>>> a = np.array([1,2,3,4])  
>>> print (a)
[1 2 3 4]

>>> print (np.average(a))
2.5
>>> print (np.mean(a))
2.5
# 指定权重
>>> wts = np.array([4,3,2,1])  
>>> print (np.average(a,weights = wts))
2.0
# 如果 returned 参数设为 true,则返回权重的和  
>>> print (np.average([1,2,3,4],weights =  [4,3,2,1], returned =  True))
(2.0, 10.0)

考虑数组[1,2,3,4]和相应的权重[4,3,2,1],利用average()函数将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。

7.杂项

【十一、例7】clip等实例

>>> a = np.random.randint(-5,5,[5,5])
>>> print(a)
>>> print(np.clip(a,a_min=-2,a_max=3))
>>> print(np.abs(a))
>>> print(np.absolute(a))
>>> print(np.sign(a))

np.clip是用来替换的,将小于a_min的值换成a_min,将大于a_max的值换成a_max。

np.abs和np.absolute的功能类似,返回元素的绝对值。

np.sign类似于符号函数,负数返回-1,正数返回1,零返回0。

十二、逻辑函数

前言

关于逻辑函数的内容,我们在之前11章或多或少都穿插过一些,这里我们就做一个简单的整理。

1.真值测试

真值测试包含np.all()np.any()两种方法:

  • np.all()判断是否全为真:如果是就返回True;否则返回False。
  • np.any()判断是否至少有一个为真:如果有就返回True;否则返回False。

举例:

【十二、例1】真值测试举例

>>> a = np.random.randint(0,5,10)
>>> b = np.random.randint(0,5,10)
>>> print(a)
[4 1 0 2 4 0 1 0 4 4]
>>> print(b)
[0 2 1 4 4 2 4 2 0 0]
>>> print(np.all(a==a))
True
>>> print(np.all(a==b))
False
>>> print(np.any(a==b))
True
>>> print(np.all([2,np.nan]))
True

其实a==a,a==b只是一个前置环节,目的是为了拿到布尔类型的数组便于真值判断。

而真值判断的不仅仅是True和False,0和非0等。如上面最后一个例子,numpy中的nan并不是空对象,其实际上是numpy.float64对象,所以我们不能误认为其是空对象,从而用bool(np.nan)去判断是否为空值,这是不对的。

2.数组内容

如上,nan类型并不能通过np.all()区分,那么需要有一种方法判断一个元素是否为nan,所以numpy提供了np.isnan()来判断:

【十二、例2】isnan()举例

>>> print(np.isnan([2,3.0,np.nan,4]))
[False False  True False]

3.逻辑运算

我们之前已经见过一些常见的逻辑运算,现在让我们来归纳一下:

  • not 逻辑非
  • and 逻辑与
  • or 逻辑或
  • xor 逻辑异或

【十二、例3】逻辑运算举例

>>> a = np.random.randint(0,5,10)>3
>>> print(a)
[False False False  True False  True False False False  True]
>>> b = np.random.randint(0,5,10)<2
>>> print(b)
[False False  True False  True False False False  True  True]
>>> print(np.logical_not(a))
[ True  True  True False  True False  True  True  True False]
>>> print(np.logical_and(a,b))
[False False False False False False False False False  True]
>>> print(np.logical_or(a,b))
[False False  True  True  True  True False False  True  True]
>>> print(np.logical_xor(a,b))
[False False  True  True  True  True False False  True False]

4.对照

  • greater: >
  • greater_equal: >=
  • equal: ==
  • not_equal: !=
  • less: <
  • less_equal: <=
  • isclose:是否接近
  • allclose:是否全部接近

其中它们返回的都是布尔类型的ndarray数据类型。

【十二、例4】对照举例

>>> a = np.random.randint(0,5,10)
>>> print(a)
[3 1 4 1 0 0 4 1 0 4]
>>> print(np.greater(a,2))
[ True False  True False False False  True False False  True]
>>> print(np.greater_equal(a,2))
[ True False  True False False False  True False False  True]
>>> print(np.less(a,3))
[False  True False  True  True  True False  True  True False]
>>> print(np.less_equal(a,3))
[ True  True False  True  True  True False  True  True False]
>>> print(np.equal(a,2))
[False False False False False False False False False False]
>>> print(np.not_equal(a,2))
[ True  True  True  True  True  True  True  True  True  True]
>>> print(np.isclose([1e10,1e-8], [1.0001e10,1e-9]))
[False  True]

allclose等同于isclose+logical_and的功能,isclose(a,b)返回True的前提是:

absolute(a - b) <= (atol + rtol * absolute(b))

而atol,rtol有默认值:

在这里插入图片描述
分别是1e-05和1e-08。

注意,上面的例子np.isclose([1e10,1e-8], [1.0001e10,1e-9])特别容易把[1e10,1e-8]和[1.0001e10,1e-9]分别各自计算,而忘了这是numpy的向量化特性,应该a1和b1计算,a2和b2计算,而不是交叉。

练习

1.1 将数组a中大于30的值替换为30,小于10的值替换为10。

a = np.random.uniform(1, 50, 20)
【知识点:数学函数、搜索】
如何将大于给定值的所有值替换为给定的截止值?

>>> a = np.random.uniform(1, 50, 20)
>>> print(a)
[ 7.19058684 49.12313599 32.52869105 39.04000862 23.38656207 39.5669858
 47.66534534 23.78614171 25.31796867 43.63880653 35.63643244 43.36053041
 19.4943527  41.04586366 33.8073533  42.4145023   3.51140163 16.86435799
 15.41111577 48.89610467]
>>> print(np.clip(a,a_max=30,a_min=10))
[10.         30.         30.         30.         23.38656207 30.
 30.         23.78614171 25.31796867 30.         30.         30.
 19.4943527  30.         30.         30.         10.         16.86435799
 15.41111577 30.        ]

1.2 找到一个一维数字数组a中的所有峰值。峰顶是两边被较小数值包围的点。

a = np.array([1, 3, 7, 1, 2, 6, 0, 1])
【知识点:数学函数、搜索】

如何在一维数组中找到所有的局部极大值(或峰值)?

>>> a = np.array([1, 3, 7, 1, 2, 6, 0, 1])
>>> b1 = np.diff(a)
>>> print(b1)
[ 2  4 -6  1  4 -6  1]
>>> b2 = np.sign(b1)
>>> print(b2)
[ 1  1 -1  1  1 -1  1]
>>> b3 = np.diff(b2)
>>> print(b3)
[ 0 -2  2  0 -2  2]
>>> print(np.where(np.less(b3, -2))[0]+1)
[2 5]

在这里插入图片描述
为什么后面要加1,我们看图解,我们观察第一个-2(索引为1),由于进行了两次diff,所以-2代表着“索引为3的元素与前面的差值的符号值”减去“索引为2的元素与前面的差值的符号值”,若等于-2,-2 = -1-(1),说明遇到一个波峰,波峰位置在当前元素的前一个位置,所以因为两个diff整体向右偏移2个单位,又因为实际意义所以向左偏移1个单位,因为需要+1。

1.3 对于给定的一维数组,计算窗口大小为3的移动平均值。

z = np.random.randint(10, size=10)
【知识点:数学函数】

如何计算numpy数组的移动平均值?

>>> a = np.random.randint(10, size=10)
>>> print(a)
[8 8 4 0 6 9 0 0 0 2]
>>> b = np.cumsum(a)
>>> print(b)
[ 8 16 20 20 26 35 35 35 35 37]
>>> c = b[3:]-b[:-3]
>>> print(c)
[12 10 15 15  9  0  2]
>>> print(np.insert(c,0,b[2])/3)
[6.66666667 4.         3.33333333 5.         5.         3.
 0.         0.66666667]

思路是利用np.cumsum求累计和,然后用b[3:]b[:-3]作差,最后在前面补上前三个数之和,然后/3。

1.4 对一个5x5的随机矩阵做归一化

-Z = np.random.random((5,5))

【知识点:数学函数】

(提示: (x - min) / (max - min))

>>> Z = np.random.random((5,5))
>>> Zmax = np.amax(Z)
>>> Zmin = np.amin(Z)
>>> Z = (Z - Zmin)/(Zmax - Zmin)
>>> print(Z)
[[0.10568128 0.73839058 0.7003277  0.88136793 0.22216305]
 [1.         0.         0.57082622 0.99064189 0.12630644]
 [0.44879517 0.68146185 0.23517688 0.40715598 0.17199997]
 [0.75392191 0.82686359 0.86101898 0.74630194 0.87936145]
 [0.61444103 0.32236079 0.44436892 0.44736663 0.21636769]]

1.5 用五种不同的方法去提取一个随机数组的整数部分

Z = np.random.uniform(0,10,10)
【知识点:数学函数】

(提示: %, np.floor, np.ceil, astype, np.trunc)

>>> def convInt(x):
>>>     return np.array(x,dtype=int)

#第一种% 取余数
>>> Y = convInt(Z-Z%1)
>>> print(Y)
[7 6 1 7 6 2 5 7 8 5]
#第二种ceil 向上取整
>>> Y = convInt(np.ceil(Z)-1)
>>> print(Y)
[7 6 1 7 6 2 5 7 8 5]
#第三种floor 向下取整
>>> Y = convInt(np.floor(Z))
>>> print(Y)
[7 6 1 7 6 2 5 7 8 5]
#第四种 直接转换
>>> print(convInt(Z))
[7 6 1 7 6 2 5 7 8 5]
#第五种  函数返回输入数组元素的截断值
>>> print(convInt(np.trunc(Z)))
[7 6 1 7 6 2 5 7 8 5]

这里需要注意的是,如果不使用自定义的convInt()函数,那么生成的数组是浮点型。

1.6 考虑一维数组Z,构建一个二维数组,其第一行为(Z [0],Z [1],Z [2]),随后的每一行都移位1(最后一行应为(Z [ -3],Z [-2],Z [-1])

【知识点:数学函数】

(提示np.lib.stride_tricks)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]-------->image.png

>>> def rolling(a, window):
>>>     shape = (a.size - window + 1, window)
>>>     print(shape)
>>>     strides = (a.itemsize, a.itemsize)
>>>     print(a,a.itemsize)
>>>     print(strides)
>>>     return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
>>> Z = rolling(np.arange(12), 3)
>>> print(Z)
(10, 3)
[ 0  1  2  3  4  5  6  7  8  9 10 11] 8
(8, 8)
[[ 0  1  2]
 [ 1  2  3]
 [ 2  3  4]
 [ 3  4  5]
 [ 4  5  6]
 [ 5  6  7]
 [ 6  7  8]
 [ 7  8  9]
 [ 8  9 10]
 [ 9 10 11]]

shape 为变形后的形状,strides中各个数字为每一“步”的字节数,其中当前元素横纵到下一个的步数(先列后行),所以分别都移动1*itemsize。

1.7 考虑两组点集P0和P1去描述一组线(二维)和一个点p,如何计算点p到每一条线 i (P0[i],P1[i])的距离?

P0 = np.random.uniform(-10,10,(10,2))
P1 = np.random.uniform(-10,10,(10,2))
p = np.random.uniform(-10,10,( 1,2))
【知识点:数学函数】

提示 设P(x0,y0),直线方程为:Ax+By+C=0 则P到直线的距离为:d=|Ax0+By0+C|/√(A²+B²)

>>> def distance(P0,P1,p):
>>>     A=-1/(P1[:,0]-P0[:,0])
>>>     B=1/(P1[:,1]-P0[:,1])
>>>     C=P0[:,0]/(P1[:,0]-P0[:,0])-P0[:,1]/(P1[:,1]-P0[:,1])
>>>     return np.abs(A*p[:,0]+B*p[:,1]+C)/np.sqrt(A**2+B**2)
>>> P0 = np.random.uniform(-10,10,(10,2))
>>> P1 = np.random.uniform(-10,10,(10,2))
>>> p  = np.random.uniform(-10,10,( 1,2))
>>> print (distance(P0, P1, p))
[ 2.41120585  7.05924485  5.94906338  3.89096895  7.68364539 14.01851392
  4.28148124  2.29582076  6.19155339 15.55087594]

思路,先算A和B的值,其实这块是不能直接求的,需要转换成点斜式然后转换成截距式

1.8 画正弦函数和余弦函数, x = np.arange(0, 3 * np.pi, 0.1)?

【知识点:数学函数】

>>> import matplotlib.pyplot as plt
>>> x = np.arange(0, 3 * np.pi, 0.1)
>>> y = np.sin(x)
>>> plt.plot(x,y,'g')
>>> y = np.cos(x)
>>> plt.plot(x,y,'b')

在这里插入图片描述

1.9 减去矩阵每一行的平均值 ?

【知识点:数学函数】

>>> X = np.random.randint(1,10,(5,5))
>>> print(X)
[[8 1 5 2 8]
 [1 1 7 4 5]
 [5 2 8 5 1]
 [6 9 8 4 2]
 [1 8 6 6 1]]
>>> Y = X - X.mean(axis=1)
>>> print(X.mean(axis=1))
[4.8 3.6 4.2 5.8 4.4]
>>> print(Y)
[[ 3.2 -2.6  0.8 -3.8  3.6]
 [-3.8 -2.6  2.8 -1.8  0.6]
 [ 0.2 -1.6  3.8 -0.8 -3.4]
 [ 1.2  5.4  3.8 -1.8 -2.4]
 [-3.8  4.4  1.8  0.2 -3.4]]

提示: mean(axis=,keepdims=)

1.10 进行概率统计分析 ?

arr1 = np.random.randint(1,10,10)
arr2 = np.random.randint(1,10,10))
【知识点:数学函数】
平均数,中位数,方差,标准差,相关性矩阵,协方差矩阵等

>>> arr1 = np.random.randint(1,10,10)
>>> arr2 = np.random.randint(1,10,10)
>>> print(np.mean(arr1))
5.2
>>> print(np.median(arr1))
6.0
>>> print(np.var(arr1))
6.36
>>> print(np.std(arr1))
2.5219040425836985
>>> print(np.cov(arr1,arr2))
[[7.06666667 2.6       ]
 [2.6        4.45555556]]
>>> print(np.corrcoef(arr1,arr2))
[[1.         0.46335634]
 [0.46335634 1.        ]]

2.1 获取a和b元素匹配的位置。

a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])
b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])
【知识点:逻辑函数】

如何得到两个数组元素匹配的位置?

>>> a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])
>>> b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])
>>> print(np.where((a==b)==True)[0])
[1 3 5 7]

思路,先用a==b利用向量化特性判断出a、b数组每个位置上是否相等,然后通过np.where来找到相等的地方,注意它返回的是一个二维数组,合格的下标索引在[0]这里。

2.2 获取5到10 之间的所有元素。

a = np.array([2, 6, 1, 9, 10, 3, 27])
【知识点:逻辑函数】

如何从numpy数组中提取给定范围内的所有元素?

>>> a = np.array([2, 6, 1, 9, 10, 3, 27])
>>> print(a[np.logical_and(a>=5,a<=10)])
[ 6  9 10]

利用np.logical_and以及numpy向量化特点实现。

2.3 对于两个随机数组A和B,检查他们是否相等

A = np.random.randint(0,2,5)
B = np.random.randint(0,2,5)
【知识点:逻辑函数】

(提示: np.allclose, np.array_equal)

>>> A = np.random.randint(0,2,5)
>>> B = np.random.randint(0,2,5)
>>> print(A)
[0 1 0 1 1]
>>> print(B)
[1 0 1 0 1]
>>> print(np.allclose(A,B))
False

2.4 何对布尔值取反,或者原位(in-place)改变浮点数的符号(sign)?

【知识点:逻辑函数】

(提示: np.logical_not, np.negative)

>>> Z = np.random.uniform(-1.0,1.0,10)
>>> print(Z)
>>> print(Z*-1)

2.5 找出数组中与给定值最接近的数

【知识点:逻辑函数】

(提示: np.abs().argmin())

>>> Z=np.array([[0,1,2,3],[4,5,6,7]])
>>> print(Z)
[[0 1 2 3]
 [4 5 6 7]]
>>> z=5.1
>>> print(np.ravel(Z)[np.abs(Z - z).argmin()])
5

思路,argmin()返回的是最小值的索引(扁平化后),我们可以通过它利用np.ravel()`找到所求元素。

参考文章

1.https://blog.csdn.net/weixin_38287297/article/details/81430733

2.https://www.runoob.com/numpy/numpy-binary-operators.html

3.https://blog.csdn.net/weixin_46559271/article/details/105188300

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页