掌握NumPy数组索引技巧:基础索引与切片索引详解

数据处理领域,Numpy的数组索引就像一座宝藏,里面蕴藏着提取数据子集和元素的多种方法。掌握了它,无疑能显著提升数据处理效率。今天,我们就来详细研究一下。

一维数组索引

一维数组索引的使用非常方便。只需在中括号内标明索引,就能直接定位到第i个元素。而且,计数是从0开始的。比如,对于数组a=[1, 2, 3, 4, 5],输入a[2]就能得到元素3。这样的操作既简单又明了,对于快速定位特定元素非常有帮助,是编程基础中的核心内容。

操作时,务必留意索引值不要越界。以长度为5的数组为例,若试图访问a[5],系统将报错。所以,动手前先核实数组长度,避免犯此类低级错误。

import numpy as np
arr = np.arange(9).reshape((3,3))
arr[0]  # array([0, 1, 2])
arr[0][0]  # 0
arr[0,0]   # 0

多维数组的索引确实挺复杂的。以二维数组为例,每个索引对应的不只是一个数字,而是一组数字。比如,看看这个二维数组b = [[1, 2, 3], [4, 5, 6]],当你输入b[0]时,它就会给你一个包含1、2、3的数组。

这种索引系统可对多维数组各维度的数据实施灵活操作。想象在多层建筑中寻找,每层有众多房间,只需定位到特定位置,即可精准找到并取出所需物品。

获取单个元素

arr[:2,1:]
"""
array([[1, 2],
       [4, 5]])
"""

元素可以被反复搜索,或者通过索引列表来选择。比如,对于二维数组b,若要查找第5个元素,可以用b[1][1]这样的方式。如果给出索引列表,例如b[[1, 1]],同样可以找到目标元素。

arr[0,:]  # array([0, 1, 2]) 获取第1行
arr[:,0]  # array([0, 3, 6]) 获取第1列

这种操作非常适合做详细的数据筛选。面对繁杂的资料,利用这一特性,我们能快速且精确地找到所需的一个或多个特定数据,进而为接下来的数据分析筑牢基础。

arr[::-1,::-1]   # 对整个数组进行逆序
"""
array([[6, 7, 8],
       [3, 4, 5],
       [0, 1, 2]])
"""
arr[::-1,:]   #行逆序
"""
array([[6, 7, 8],
       [3, 4, 5],
       [0, 1, 2]])
"""
arr[:,::-1]  # 列逆序
"""
array([[2, 1, 0],
       [5, 4, 3],
       [8, 7, 6]])
"""

数组视图问题

具体来说,通过这种方式获取的信息实际上是原始数组的复制。换言之,对复制数据的改动会直接影响原始数组。举例来说,若对b[1][1]的值进行了修改,那么原始数组b在同一位置的数据也会发生改变。

在实际操作中,人们常常忽略了这一点。一旦操作出现差错,原有的数据可能会被改动。所以,若想保留原始数据不变,就必须采取一些额外手段,比如进行数据备份,来确保数据的安全性。

bool_arr = arr>3
arr[bool_arr]   # array([4, 5, 6, 7, 8])

切片索引功能

Numpy的切片功能与列表切片的语法一致,使用起来十分便捷。我们可以按需通过切片手段选取子数组。以数组a为例,通过a[1:3]即可获取从索引1至2的元素。

arr = np.array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
arr2 = arr[ arr>3]
arr2 = -1
arr
"""
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
"""

图片[1]-掌握NumPy数组索引技巧:基础索引与切片索引详解-东山笔记

切片索引能设置起始、终止和步长,以此实现数组的多种分割方式。这种设计让数据整理变得快捷,能迎合不同应用场景,是处理数组信息的有效工具。

切片索引视图特性

np.count_nonzero(arr>3) # 5

切片索引操作简便,但与基础索引类似,它只是对原始数组的视图进行了操作。修改切片中的数据时,这些变动会自动同步到原始数组。比如,若对数组a的1至3切片进行修改,数组a本身也会随之改变。

用户需透彻掌握该功能,准确运用它以实现数据处理的最佳效果。操作时,务必分清是视图还是副本,以免误改原始资料,保证整个数据处理流程的精确性。

np.sum(arr>3)  # 5
#每一列中大于3的个数
np.sum(arr>3,axis=0)  # array([1, 2, 2])

布尔索引原理

np.all(arr>3)  # False   all 全部为True时,返回True,否则返回False
np.any(arr>3)  # True    any 至少有一个为True时,返回True,否则返回False
# np.all() 和 np.any()也可以沿着特定的轴。 
np.all(arr>7,axis=0)  # array([False, False, False])
np.any(arr>7,axis=0)   # array([False, False,  True])

布尔索引主要依赖布尔数组。这些数组之间的比较可以批量进行,从而产生同样形状和长度的布尔数组。比如,数组a与一个特定数值相比,就能得到一个形状和长度与a相同的布尔数组。

这使得挑选符合特定条件的数据变得简便。借助布尔数组,我们可以轻松地锁定标记为真的元素,从而筛选出符合要求的信息。

布尔索引结果特点

选取的子数组基于布尔索引,仅为原始数组的复制品。对其进行操作,不会影响原始数组。编辑或处理筛选出的数据,不必担心会对原始数据造成不良后果。

# 每个元素逐位逻辑运算
a = np.array([1,0,1,1,0],dtype=bool)
b = np.array([1,0,1,1,0],dtype=bool)
a & b  # array([ True, False,  True,  True, False])

使用np.count_nonzero函数可以计算布尔数组中真值的个数,而np.sum函数同样可以达到这个目的,因为在这个函数中,False会被当作0来计算,而True则被计为1。这两种方法在数据统计分析领域非常实用,能快速提供我们需要的统计结果。

布尔数组逻辑运算

a = np.array([1,0,1,1,0],dtype=bool)
b = np.array([1,0,1,1,0],dtype=bool)
a and b 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

普通的“与”和“或”符号在布尔数组中不起作用。必须使用逐位逻辑运算符“与”(&)、“或”(|)和“异或”(^)。用“与”或“或”符号处理,会将数组视为一个整体。而“与”、“或”以及“异或”运算符则是逐位对数组元素进行操作。

a和b出错,是因为它们未能准确辨识数组的全部真伪。若使用np.all()或np.any(),则能有效评估整个数组。在复杂的数据筛选与逻辑判断过程中,恰当地运用这些运算符至关重要。

数组索引使用

a = np.array([1,0,1,1,0],dtype=bool)
b = np.array([1,0,1,1,0],dtype=bool)
np.all(a) and np.any(b)  # False

数组索引能够一次获取多个数据元素,操作流程并不繁琐。然而,在使用过程中,有两个要点必须留意。一点是,最终输出的数据形状可能与最初的索引数组不一致,其表现形式会依照索引数组的结构来定。

重复操作索引可能会带来意料之外的效果。例如,当你对x的[0,0]位置加一,所得结果可能并不如你所想。这主要是因为它的赋值过程与你原先的设想存在偏差。为了更好地理解这一点,我们可以通过一个简单的例子来说明。

索引方式混合运用

arr[[1,2]]
"""
array([[3, 4, 5],
       [6, 7, 8]])
"""
arr[[1,2],[0,1]]
# array([3, 7]) 分别获取[1,0],[2,1]

Numpy数组的索引功能相当丰富,包括基础的索引、切片索引、布尔索引和数组索引等。这些索引方式可以灵活组合使用。只要熟练掌握每种索引的特点,就能在实际操作中灵活运用,实现各种组合。

面对处理数据的繁重任务,这种方法综合运用后,我们的数据处理效果和水平得到了显著提升。通过巧妙融合多种索引技术,我们得以快速且精确地获取所需信息,进而为数据分析开辟了更广阔的空间。

在使用Numpy数组索引时,大家是否遇到过特别棘手的问题?若有,请点赞并分享此文,也欢迎在评论区分享你的经历。

arr.shape  # (3, 3)
ind = np.array([[0,2],[1,2]])    
arr[ind].shape  # (2, 2, 3)

© 版权声明
THE END
喜欢就支持一下吧
分享