本文是根据
DataWhale
『巨硬的numpy
』文档进行学习, 辅之以天池平台, 之前学习过, 此时进行进一步的整理, 着重学习未完全熟悉的知识点.详细的代码我也放入了天池学习的AI训练营合集中
副本与视图
需要注意的是, 对数组的复制不能简单的直接使用赋值符号, 在数组中存在副本与视图一说.
- 副本可以使用
copy()
来创建, 并且对副本数据进行修改, 并不会影响原本的数据, 它们指向不同的内存. - 但是对于视图, 却是指向同一个内存地址的, 修改视图也会修改原始数据.
1 | x = np.ones((4,4),dtype='int32') |
这点 copy()
可以与之前在 list
时提到过的深拷贝与浅拷贝进行对比学习, 两者的 copy()
并不一样, 更严格来说是 list
和 ndarray
不一样.
1 | l1 = [[1,2],[3,4]] |
索引和切片
整数索引
想要直接获取数组中的单个元素,直接使用和 list
类似的方法就可以了, 也可以使用类似坐标形式的 [1,1]
.
1 | a = np.arange(9).reshape(3,3) |
切片
切片操作是指抽取数组的一部分元素生成新数组.
需要注意的是:
- 对
list
进行切片操作得到的数组是原数组的副本;- 而对
Numpy
数据进行切片操作得到的数组则是指向相同内存的视图.
由于和 list 切片方法类似, 所以下面就举几个例子
1 | x = np.arange(1, 9) |
对于二维的数组, [x][y]
这种格式的切片与 [x, y]
格式的切片结果是不一样的.
[x, y]
: 是同时对两个维度『行和列』进行切片[x][y]
: 是先对第一维『行』axis=0
进行切片[x]
, 然后在此基础上再进行第一维『行』axis=0
切片[y]
得到最终结果, 所以实际上是对一个维度切片两次, 而不是进行二维的切片.
1 | x = np.arange(9).reshape(3,3) |
dots 索引
numpy
可以使用 ...
来表示足够多的冒号, 从而在高维数组切片中表示完整的索引列表.
比如,如果 x 是 5 维数组:
x[1,2,...]
等价于x[1,2,:,:,:]
x[...,3]
等价于x[:,:,:,:,3]
x[4,...,5,:]
等价于x[4,:,:,5,:]
整数数组索引和切片
索引中使用 list
, 来表示同时取多个值.
1 | a = np.arange(1, 13).reshape(3,4) |
整数数组索引也可以结合 np.take(a, indices, axis=None, out=None, mode='raise')
使用, 可以指定索引作用的轴, 若不指定轴, 则是数组按行顺序的第几个, 更多参数可以另外查询.
1 | x = np.arange(1, 13).reshape(3,4) |
需要注意的是: 整数索引数组得到结果是新数组(新副本), 而切片得到的结果是数组的子数组(小视图).
1 | x = np.arange(1, 6) |
布尔索引
布尔索引是由布尔值组成的索引, 一般作用就是根据条件进行筛选.
1 | x = np.arange(1, 9) |
如果需要对布尔索引取反, 则可以使用 logical_not
操作, 同理, 还有 and, or, xor
.
1 | x = np.array([np.nan, 1, 2, np.nan, 3, 4, 5]) |
需要注意的是, 对于多维数组, 使用布尔索引筛选得到的结果依旧是一维的.
1 | x = np.arange(9).reshape(3,3) |
个人收获
学到了 dots
索引, 之前觉得跟 :
完全一模一样, 因为是在二维数组中, 但是到了高维数组中就可以实现简单写法了.
使用 logical_and
等 对布尔数组进行逻辑操作的『优雅』写法.
最重要的是理清楚了副本与视图之间的关系, 使得之前进行数组操作的一些迷糊地方更深刻, 总结来说还是深浅拷贝的坑 💫, 这次整理清楚了!