【Python系列专栏】第五十六篇Python中Numpy 数组元素的获取
通过索引和切片的方式获取数组元素,一维数组元素的获取与列表、元组的获取方式一样:
·
数组元素的获取
通过索引和切片的方式获取数组元素,一维数组元素的获取与列表、元组的获取方式一样:
In [60]: arr7 = np.arange(10)
In [61]: arr7
Out[61]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [62]: arr7[3] #获取第4个元素
Out[62]: 3
In [63]: arr7[:3] #获取前3个元素
Out[63]: array([0, 1, 2])
In [64]: arr7[3:] #获取第4个元素即之后的所有元素
Out[64]: array([3, 4, 5, 6, 7, 8, 9])
In [65]: arr7[-2:] #获取末尾的2个元素
Out[65]: array([8, 9])
In [66]: arr7[::2] #从第1个元素开始,获取步长为2的所有元素
Out[66]: array([0, 2, 4, 6, 8])
补充一下,如果要获取多个元素,且它们的索引没有固定步长这样的规则的话,可以传入一个list作为索引:
>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a[[0,3,4]] #返回数组的第1,4,5个元素
array([0, 3, 4])
二维数组元素的获取:
In [67]: arr8 = np.arange(12).reshape(3,4)
In [68]: arr8
Out[68]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [69]: arr8[1] #返回数组的第2行
Out[69]: array([4, 5, 6, 7])
In [70]: arr8[:2] #返回数组的前2行
Out[70]:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
In [71]: arr8[[0,2]] #返回指定的第1行和第3行
Out[71]:
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11]])
In [72]: arr8[:,0] #返回数组的第1列
Out[72]: array([0, 4, 8])
In [73]: arr8[:,-2:] #返回数组的后2列
Out[73]:
array([[ 2, 3],
[ 6, 7],
[10, 11]])
In [74]: arr8[:,[0,2]] #返回数组的第1列和第3列
Out[74]:
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
In [75]: arr8[1,2] #返回数组中第2行第3列对应的元素
Out[75]: 6
布尔索引,即索引值为True和False,需要注意的是布尔索引必须是数组对象。
In [76]: log = np.array([True,False,False,True,True,False])
In [77]: arr9 = np.arange(24).reshape(6,4)
In [78]: arr9
Out[78]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
In [79]: arr9[log] #返回所有为True的对应行
Out[79]:
array([[ 0, 1, 2, 3],
[12, 13, 14, 15],
[16, 17, 18, 19]])
In [80]: arr9[-log] #通过负号筛选出所有为False的对应行
Out[80]:
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[20, 21, 22, 23]])
举一个场景,一维数组表示区域,二维数组表示观测值,如何选取目标区域的观测?
In [81]: area = np.array(['A','B','A','C','A','B','D'])
In [82]: area
Out[82]:
array(['A', 'B', 'A', 'C', 'A', 'B', 'D'],
dtype='<U1')
In [83]: observes = np.arange(21).reshape(7,3)
In [84]: observes
Out[84]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17],
[18, 19, 20]])
In [85]: observes[area == 'A'] #这里[]内的"area == 'A'"语句返回的就是一个全是布尔值的数组对象
Out[85]:
array([[ 0, 1, 2],
[ 6, 7, 8],
[12, 13, 14]])
返回所有A区域的观测。
In [86]: observes[(area == 'A') | (area == 'D')] #条件值需要在&(and),|(or)两端用圆括号括起来
Out[86]:
array([[ 0, 1, 2],
[ 6, 7, 8],
[12, 13, 14],
[18, 19, 20]])
返回所有A区域和D区域的观测。
当然,布尔索引也可以与普通索引或切片混合使用:
In [87]: observes[area == 'A'][:,[0,2]]
Out[87]:
array([[ 0, 2],
[ 6, 8],
[12, 14]])
返回A区域的所有行,且只获取第1列与第3列数据。
花式索引:实际上就是将数组作为索引将原数组的元素提取出来
In [88]: arr10 = np.arange(1,29).reshape(7,4)
In [89]: arr10
Out[89]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24],
[25, 26, 27, 28]])
In [90]: arr10[[4,1,3,5]] #按照指定顺序返回指定行
Out[90]:
array([[17, 18, 19, 20],
[ 5, 6, 7, 8],
[13, 14, 15, 16],
[21, 22, 23, 24]])
In [91]: arr10[[4,1,5]][:,[0,2,3]] #返回指定的行与列,可以分解为两条命令来看
Out[91]:
array([[17, 19, 20],
[ 5, 7, 8],
[21, 23, 24]])
In [92]: arr10[[4,1,5],[0,2,3]] # 返回指定位置的数字
Out[92]: array([17, 7, 24])
请注意!这与上面的返回结果是截然不同的,上面的命令返回的是二维数组,而这条命令返回的是一维数组。P.S.原文这里没有解释的很清楚,简单来说,如果在方括号内使用两个甚至多个数组/列表作为索引,中间以逗号分割,那么数组的顺序对应的就是从低维到高维,比如 In [92]
中第一个列表的第一个元素是4,第二个列表的第一个元素是0,这就表示要从arr10这个二维数组中取出的第一个元素在第一维第5个对象和第二维第1个对象交叠的地方,也即二维数组的第5行第1个元素17。最后会将所有取出的元素放入一个一维数组中返回。但如果某一维没有用数组/列表指定,而是使用了冒号表示取所有的话,返回的就是二维对象了。再举一个例子吧:
>>> a = np.arange(10).reshape(2,5)
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> a[:,[0,4]]
array([[0, 4],
[5, 9]])
>>> a[[0,0,1,1],[0,4,0,4]]
array([0, 4, 5, 9])
如果想使用比较简单的方式返回指定行与列的二维数组的话,可以使用ix_()函数
In [93]: arr10[np.ix_([4,1,5],[0,2,3])] # 允许我们用指定位置的方式,并且保持返回的数组形状不变
Out[93]:
array([[17, 19, 20],
[ 5, 7, 8],
[21, 23, 24]])
这与 arr10[[4,1,5]][:,[0,2,3]]
返回的结果是一致的。
更多推荐
已为社区贡献1条内容
所有评论(0)