我是靠谱客的博主 欣慰哈密瓜,最近开发中收集的这篇文章主要介绍Numpy进阶之Less基础,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

花式索引和索引技巧:

>>> a = np.arange(12)**2
>>> a
array([
0,
1,
4,
9,
16,
25,
36,
49,
64,
81, 100, 121],
dtype=int32)
>>> i = np.array([1,1,3,5,8])
>>> a[i]
array([ 1,
1,
9, 25, 64], dtype=int32)
>>> j = np.array([[3,4],[9,7]])
>>> a[j]
array([[ 9, 16],
[81, 49]], dtype=int32)
>>> a[[j]]
array([[ 9, 16],
[81, 49]], dtype=int32)
>>> a[np.array([i,i])]
array([[ 1,
1,
9, 25, 64],
[ 1,
1,
9, 25, 64]], dtype=int32)
>>>

我们也可以给出多个维度的索引。每个维度的索引数组必须具有相同的形状。

>>> a = np.arange(12)
>>> a.shape=3,4
>>> a
array([[ 0,
1,
2,
3],
[ 4,
5,
6,
7],
[ 8,
9, 10, 11]])
>>> i = np.array([[0,1]])
>>>> i = np.array([[0,1],[1,2]])
>>> j = np.array([[2,1],[3,3]])
>>> a[i,j]
array([[ 2,
5],
[ 7, 11]])
>>> a[i,j]
array([[ 2,
5],
[ 7, 11]])
>>> l = [i,j]
>>> a[l]
array([[ 2,
5],
[ 7, 11]])
>>> a[:,j]
array([[[ 2,
1],
[ 3,
3]],
[[ 6,
5],
[ 7,
7]],
[[10,
9],
[11, 11]]])
>>>

最后那种情况是对每一行进行索引。
我们不能将 i 和 j 放入一个数组中,因为这个数组将被解释为索引第一个维度。

>>> s = np.array([i,j])
>>> a[s]
Traceback (most recent call last):
File "<pyshell#174>", line 1, in <module>
a[s]
IndexError: index 3 is out of bounds for axis 0 with size 3
>>> a.size
12
>>> a.shape
(3, 4)
>>> a
array([[ 0,
1,
2,
3],
[ 4,
5,
6,
7],
[ 8,
9, 10, 11]])
>>> a[tuple(s)]
array([[ 2,
5],
[ 7, 11]])
>>> s
array([[[0, 1],
[1, 2]],
[[2, 1],
[3, 3]]])
>>>

索引数组的另一个常见用途是搜索时间相关序列的最大值:

>>> time = np.linspace(20,145,5)
>>> time
array([ 20.
,
51.25,
82.5 , 113.75, 145.
])
>>> data = np.sin(np.arange(20)).reshape(5,4)
>>> data
array([[ 0.
,
0.84147098,
0.90929743,
0.14112001],
[-0.7568025 , -0.95892427, -0.2794155 ,
0.6569866 ],
[ 0.98935825,
0.41211849, -0.54402111, -0.99999021],
[-0.53657292,
0.42016704,
0.99060736,
0.65028784],
[-0.28790332, -0.96139749, -0.75098725,
0.14987721]])
>>> ind = data.argmax(axis=0)
>>> ind
array([2, 0, 3, 1], dtype=int64)
>>> time_max = time[ind]
>>> time_max
array([ 82.5 ,
20.
, 113.75,
51.25])
>>> data_max = data[ind,range(data.shape[1])]
>>> data_max
array([0.98935825, 0.84147098, 0.99060736, 0.6569866 ])
>>> np.all(data_max == data.max(axis=0))
True
>>>

可以使用数组索引作为目标来赋值:

>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a[[1,3,4]]=-1
>>> a
array([ 0, -1,
2, -1, -1])
>>>

然而,当索引列表包含重复时,赋值完成多次,留下最后一个值:

>>> a = np.arange(5)
>>> a[[1,1,1]] = [-1,-2,-3]
>>> a
array([ 0, -3,
2,
3,
4])

如果你想使用Python的 += 构造要小心,因为这可能得不到你想要的效果:

>>> a = np.arange(5)
>>> a[[0,0,2]] += 1
>>> a
array([1, 1, 3, 3, 4])

即使0在索引列表中出现两次,第0个元素只会增加一次。这是因为Python要求“a + = 1”等同于“a = a + 1”。

使用布尔值作为数组索引:
布尔索引最自然的方式是使用与原始数组具有相同形状的布尔数组:

>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0,
1,
2,
3],
[ 4,
5,
6,
7],
[ 8,
9, 10, 11]])
>>> b = a>4
>>> b
array([[False, False, False, False],
[False,
True,
True,
True],
[ True,
True,
True,
True]])
>>> a[b]
array([ 5,
6,
7,
8,
9, 10, 11])
>>>

注意返回的是一维数组。

这种方法常用于赋值:

>>> a[b] = 0
>>> a
array([[0, 1, 2, 3],
[4, 0, 0, 0],
[0, 0, 0, 0]])
>>>

第二种使用布尔索引的方法更类似于整数索引;对于数组的每个维度,我们给出一个一维布尔数组,选择我们想要的切片:

>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0,
1,
2,
3],
[ 4,
5,
6,
7],
[ 8,
9, 10, 11]])
>>> b1 = np.array([False,True,True])
>>> b2 = np.array([True,False,True,False])
>>> a[b1,:]
array([[ 4,
5,
6,
7],
[ 8,
9, 10, 11]])
>>> a[:,b2]
array([[ 0,
2],
[ 4,
6],
[ 8, 10]])
>>> a[b1,b2]
array([ 4, 10])
>>>

请注意,1D布尔数组的长度必须与你要切片的维度(或轴)的长度一致。在前面的示例中, b1 是rank为1的数组,其长度为3( a 中行的数量), b2 (长度4)适合于索引 a 的第二个rank(列)。

ix_()函数:

>>> a = np.array([2,3,4,5])
>>> b = np.array([8,5,4])
>>> c = np.array([5,4,6,8,3])
>>> ax,bx,cx = np.ix_(a,b,c)
>>> ax
array([[[2]],
[[3]],
[[4]],
[[5]]])
>>> bx
array([[[8],
[5],
[4]]])
>>> cx
array([[[5, 4, 6, 8, 3]]])
>>> ax.shape,bx.shape,cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))
>>> result = ax + bx * cx
>>> result
array([[[42, 34, 50, 66, 26],
[27, 22, 32, 42, 17],
[22, 18, 26, 34, 14]],
[[43, 35, 51, 67, 27],
[28, 23, 33, 43, 18],
[23, 19, 27, 35, 15]],
[[44, 36, 52, 68, 28],
[29, 24, 34, 44, 19],
[24, 20, 28, 36, 16]],
[[45, 37, 53, 69, 29],
[30, 25, 35, 45, 20],
[25, 21, 29, 37, 17]]])
>>> result.shape
(4, 3, 5)
>>> bx * cx
array([[[40, 32, 48, 64, 24],
[25, 20, 30, 40, 15],
[20, 16, 24, 32, 12]]])
>>> (bx * cx).shape
(1, 3, 5)
>>>

这里用到了广播,所以可能有点不好理解。

还有另一种实现方式:

>>> def ufunc_reduce(ufct,*vec):
vs = np.ix_(*vec)
r = ufct.identity
print("first r:",r)
for v in vs:
r = ufct(r,v)
print("r:",r)
return r
>>> ufunc_reduce(np.add,a,b,c)
first r: 0
r: [[[2]]
[[3]]
[[4]]
[[5]]]
r: [[[10]
[ 7]
[ 6]]
[[11]
[ 8]
[ 7]]
[[12]
[ 9]
[ 8]]
[[13]
[10]
[ 9]]]
r: [[[15 14 16 18 13]
[12 11 13 15 10]
[11 10 12 14
9]]
[[16 15 17 19 14]
[13 12 14 16 11]
[12 11 13 15 10]]
[[17 16 18 20 15]
[14 13 15 17 12]
[13 12 14 16 11]]
[[18 17 19 21 16]
[15 14 16 18 13]
[14 13 15 17 12]]]
array([[[15, 14, 16, 18, 13],
[12, 11, 13, 15, 10],
[11, 10, 12, 14,
9]],
[[16, 15, 17, 19, 14],
[13, 12, 14, 16, 11],
[12, 11, 13, 15, 10]],
[[17, 16, 18, 20, 15],
[14, 13, 15, 17, 12],
[13, 12, 14, 16, 11]],
[[18, 17, 19, 21, 16],
[15, 14, 16, 18, 13],
[14, 13, 15, 17, 12]]])
>>>

最后

以上就是欣慰哈密瓜为你收集整理的Numpy进阶之Less基础的全部内容,希望文章能够帮你解决Numpy进阶之Less基础所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部