numpy中的sum函数、axis/expand_dims和冒号切片

1. sum

np.sum不传参

sum函数不传参的时候代表求解所有元素的总和,用法较为简单粗暴

np.sum传参 axis

首先明确axis的作用是定位到我们要处理的数据维度,以2* 3 *2数组为例:

import numpy as np
a = np.array([[[1,2],[3,2],[3,1]],[[2,0],[1,0],[1,1]]])
print(a)

[[[1 2]
  [3 2]
  [3 1]]

 [[2 0]
  [1 0]
  [1 1]]]

如果想要定位某一个位置的元素,则需要三个axis的值共同确定,比如a[0][0][0]=1。因此在np.sum函数中,axis可取的值等于数组的维度。在本例中axis就可以取0,1,2三种数值。
我们以立方体为例来解释函数中axis取不同值情况下的运算情况:

numpy中的sum函数、axis/expand_dims和冒号切片_第1张图片

axis = 0,则说明该立方体将沿着0所在的边相加,最终结果将被压为1和2两条边所组成的二维平面,即为b * c的二维矩阵。
axis = 1,则说明该立方体将沿着1所在的边相加,最终结果将被压为0和2两条边所组成的二维平面,即为a* c的二维矩阵。
axis = 2,则说明该立方体将沿着2所在的边相加,最终结果将被压为0和1两条边所组成的二维平面,即为a * b的二维矩阵。

b = np.sum(a,axis=0)
c = np.sum(a,axis=1)
d = np.sum(a,axis=2)
    [[3 2]
     [4 2]
     [4 2]]
     
    [[7 5]
     [4 1]]
     
    [[3 5 4]
     [2 1 2]]

结果的维度3 * 2,2 * 2,3 *2,结果与我们的推论符合,因此证明这个立方体理论简洁明了且成立。

结论固然简明,但是在理解方面还是有一定难度,经常会在代码计算过程中发生混淆与不理解

在了解其他同学的工作基础上,我觉得使用括号的机制更为方便理解。将不同的axis理解成为括号的不同层次,具体的可以参考该同学的 blog,讲解的非常清楚明白。简而言之就是将axis的值与括号的不同层次联系在一起,axis=0意味着最外一层以外,axis=1意味着新加的括号位于最外一层与倒数第二层之间。

https://blog.csdn.net/qq_35860352/article/details/80463111

np.sum传参 keepdims

在以上的计算过程中,可以很明显的看出来因为在某一个方向得到压缩,导致数组的维度发生了降维,此时可以使用keepdims参数来控制维度的的缩减。

额外插入markdown对于图片插入移动居中的操作

首先将图片插入到CSDN-markdown中,此时markdown会对图片做唯一的编号
numpy中的sum函数、axis/expand_dims和冒号切片_第2张图片
此时你会得到图片唯一的网页路径,就是:https://img-blog.csdnimg.cn/20190730120536938.png
接下来可以删除原图,通过代码句段来控制原图的位置:

numpy中的sum函数、axis/expand_dims和冒号切片_第3张图片
其中center 可以替换成为 left 或者right,即更改为左对齐和右对齐两种情况;width 和 height可以更改图片大小。

顺便聊一聊由此延伸出的axis=0/1/2问题:

numpy.concatenate中有两个参数,一个是由被连接的数组组成的序列(a1, a2, …);另一个就是axis。

1、假设被连接的数组有两个,为a, b,连接之后为数组c

若axis=0,则要求除了a.shape[0]和b.shape[0]可以不等之外,其它维度必须相等。此时

     c.shape[0] = a.shape[0]+b.shape[0]

若axis=1,则要求除了a.shape[1]和b.shape[1]可以不等之外,其它维度必须相等。此时

     c.shape[1] = a.shape[1]+b.shape[1]

axis>=2 的情况以此类推,但必须要注意的是axis的值必须小于数组的维度

2、 若连接的数组只有一个,假设是三维的数组a,a.shape=(2,3,4),则看成有2个(3,4)的数组进行连接,axis的值只能为0或1,连接规则同上。也就是说,被连接的数组一定不能是一维数组,否则会报错为:ValueError: zero-dimensional arrays cannot be concatenated

2. 冒号切片

这种用法多见于list中,在list中使用冒号来进行元素的取舍。
1、单冒号用法
list[a:]即第a+1项到最后一项
list[:a]即第一项到第a项
list[a:b]即第a+1项到b项

   list = [0, 1, 2, 3]         
   print(list[2:])             [2, 3]
   print(list[:3])             [0, 1, 2]
   print(list[1:3])            [1, 2]

2、双冒号用法

list[start:end:step]
start:起始位置
end:结束位置
step:步长

如:

range(100)[20:30:2]
[20, 22, 24, 26, 28]

需要特别注意的是,双冒号后跟负一代表list内元素位置反转。
在这里插入图片描述

3. np.where

可以写作为np.where(condition, x, y)
用法一:可以通过广播的方式来返回一个n维数组。
condition, x, y, return are all can be #ndarray

x = np.random.randn((4, 4))
np.where(x>0, 4, -4)
array([[-4, -4, -4, -4],
       [ 4, -4,  4,  4],
       [-4,  4,  4,  4],
       [-4, -4, -4,  4]])

用法二:condition 也可以是布尔型数组,每个条件都和x,y对应(广播)

np.where([[True, False], [True, True]], 
          [[1, 2], [3, 4]], 
          [[9, 8], [7, 6]])

结果:

> array([[1, 8],
>        [3, 4]])

这是官方的例子,刚开始不明白意思,但这样看就一目了然:

np.where([[True, False], [True, True]], 
         [[1   , 2    ], [3   , 4   ]], 
         [[9   , 8    ], [7   , 6   ]])

对比输出的结果:
第一列分别对应conditon,x,y,以此类推第二列第三列均如此。
第一列,conditon为True,为逻辑真值,则输出x=1
第二列,False,输出y =8

用法三:找到n维数组中特定数值的索引

print(np.where (a == 8))
(array([0], dtype=int64), array([1], dtype=int64))

你可能感兴趣的:(python,module)