用Python做数据分析之Numpy(二)

基础索引和切片

numpy数组索引是一个丰富的主题,有时候给你一个数组,可能你只想对其中一部分或者个别元素进行操作,这个时候就该索引出场了。

一维数组十分简单,表面上与Python list是一样的。如下:

In [60]: arr = np.arange(10)
In [61]: arr
Out[61]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 可以使用index选取某一个元素
In [62]: arr[5]
Out[62]: 5
# 通过切片选取相邻的多个元素
In [63]: arr[5:8]
Out[63]: array([5, 6, 7])
In [64]: arr[5:8] = 12
In [65]: arr
Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])

但本质上,narray与list是不同的,区别在于,narray数组的切面是原数组的一个view,所谓view就是当切片部分被改变了,原数组也会发生改变。而list的切片则是原list一部分的拷贝,切片部分是独立的,无法通过对切片部分进行操作改变原list。之所以使用view当然是为了节约内存啦!

# 以下示例可以帮助理解
In [66]: arr_slice = arr[5:8]
In [67]: arr_slice
Out[67]: array([12, 12, 12])
In [68]: arr_slice[1] = 12345
In [69]: arr
Out[69]: array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
# 可以试着将arr换成list,进行上述操作

如果你担心使用view会出问题或者有时候view不能达到目的,可以使用copy()函数,这样就与list一样了。

接下来看一下较为复杂一点的二维数组

# 创建一个二维数组
In [72]: arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
In [73]: arr2d[2]
Out[73]: array([7, 8, 9])
# 可以通过迭代的方式选择想要的元素,如:
In [74]: arr2d[0][2]
Out[74]: 3
# narray还有一种等价的选择元素的方法,使用逗号分割符的方式
In [75]: arr2d[0, 2]
Out[75]: 3
# 得到的结果也是一样的

其实,二维数组就可以看成一个有行和列的矩阵,可以通过行索引,列索引定位到想得到的元素,下面举一个简单的例子加以说明:

In [91]: arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
In [92]: arr2d[:2, 1:]
Out[92]: array([[2, 3], [5, 6]])

接下来介绍两种特别的索引,它们与切片不同,返回的总是数组子集的拷贝,也是在使用pandas时经常用到的方法:

# 1.布尔索引
# 创建一个随机二维数组
In [100]: data = np.random.randn(3, 2)
In [101]: data
Out[101]:
array([[-1.50846056, -2.61646164],
       [ 0.85398983, -0.39198977],
       [ 0.16666416, -0.47203715]])
# 创建一个表示索引的一维数组,每一个元素分别对应data中的一行
In [102]: names = np.array(['a', 'b', 'c'])
In [103]: names
Out[103]: array(['a', 'b', 'c'], dtype='<U1')
In [104]: data[names == 'a']
Out[104]: array([[-1.50846056, -2.61646164]])

# 2.花式索引(两个中括号)
# 这种索引可以手动调整数组中每行元素的位置
In [105]: data[[2, 0, 1]]
Out[105]: 
array([[ 0.16666416, -0.47203715],
       [-1.50846056, -2.61646164],
       [ 0.85398983, -0.39198977]])

最后,再提醒大家一次,这两种方式返回的数组不是view,切记,不是view!

猜你喜欢

转载自blog.csdn.net/qq_41602324/article/details/86418627
今日推荐