numpy—切片和索引
基本切片是 Python 中基本切片概念到 n 维的扩展。 通过将start,stop和step参数提供给内置的slice函数来构造一个 Python slice对象。 此slice对象被传递给数组来提取数组的一部分。其构造函数如下
slice(start,stop,step)
- start:切片起点
- stop:切片终点
- step:切片间隔步长,如果省略则默认为1
例1
import numpy as np
a=np.arange(10)
s=slice(2,7,2)
print(a[s])
#输出为[2 4 6]
例2
#通过冒号分隔切片参数(start:stop:step)直接提供给ndarray对象,也可以获得相同的结果。
import numpy as np
a=np.arange(10)
print(a[2:7:2])
#输出为[2,4,6]
例3
import numpy as np
a=np.arange(10)
print(a[2:])
#输出为[2 3 4 5 6 7 8 9]
例4
#切片同样适用于多维数组
import numpy as np
a=np.array([[1,2],[3,4],[5,6]])
print(a[1:])
'''
输出为
[[3 4]
[5 6]]
'''
例5
#切片中可以包含省略号‘...’,如果在行位置写省略号,则会返回列,反之,返回行
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
print('第二列')
print(a[...,1])
print('第二行')
print(a[1,...])
print('第二行及以后')
print(a[1:,...])
'''
输出为:
[[1 2 3]
[4 5 6]
[7 8 9]]
第二列
[2 5 8]
第二行
[4 5 6]
第二行及以后
[[4 5 6]
[7 8 9]]
'''
索引则相当于数组元素下角标
例6
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[1][1])
#输出为5
numpy—高级索引
高级索引包括整数索引和布尔索引
整数索引
每个整数数组表示该维度的下标值。行索引包含所有行号,列索引指定要选择的元素。这里我也不太明白,但是可以大致悟出来什么意思,请看例子
例1
#这个例子输出了每一行的第一个元素
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6],[7, 8]])
y = x[[0, 1, 2, 3], [0, 0, 0, 0]]
print(y)
#输出为[1 3 5 7]
例2
#高级索引可以与切片结合完成一些操作
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
y = x[[0,1],1:3]
print(y)
'''
输出为
[[1 2]
[4 5]]
'''
布尔索引
如果我们想要使用布尔运算符(大于号小于号之类的)来对数组结果进行比较时,我们要用到布尔索引。
例1
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x[x>5])
#输出为[ 6 7 8 9 10 11]
例2
import numpy as np
x = np.array([1,2+3j,2,2j])
print(x[np.iscomplex(x)])
#输出为[2.+3.j 0.+2.j]
numpy—广播
何为广播,在进行两个数组运算时,倘若两个数组维度相同,并且每个维度的长度都相同,我们成这两个数组的形状相同这时两个数组直接进行运算就行了,如下:
import numpy as np
a=np.array([1,2,3,4])
b=np.array([10,20,30,40])
c=a+b
print(c)
输出为[11 22 33 44]
但是很多情况下两个数组的形状并不相同,如果两个形状不相同的数组进行运算,就会触发numpy的广播机制。
例如:
import numpy as np
a = np.array([[0, 0, 0],
[10, 10, 10],
[20, 20, 20],
[30, 30, 30]])
b = np.array([1, 2, 3])
print(a + b)
'''
输出为
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
'''
下面的图片展示了数组b如何通过广播与数组a兼容
广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:
对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
- 数组拥有相同形状。
- 当前维度的值相等。
- 当前维度的值有一个是 1。
numpy—迭代数组
numpy中的迭代器对象numpy.nditer提供了一种灵活访问数组的方法。迭代器最基本的任务是完成对数组的访问。
例1
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
for i in np.nditer(a):
print(i,end=' ')
#输出为1 2 3 4 5 6
数组可以进行转置,ndarray.T,转置是什么意思呢,原来的第一列变为第一行,第一行变为第一列,以此类推
例2
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
print(a.T)
'''
输出为
[[1 2 3]
[4 5 6]]
[[1 4]
[2 5]
[3 6]]
'''
遍历有两种顺序,一种是行序优先(C-order),另一种是列序优先(Fortran-order),我们可以控制遍历的顺序。
例3
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print('C-order')
for i in np.nditer(a,order='C'):
print(i,end=',')
print('\n')
print('Fortran-order')
for i in np.nditer(a,order='F'):
print(i,end=',')
'''
输出为:
C-order
1,2,3,4,5,6,
Fortran-order
1,4,2,5,3,6,
'''
修改数组中元素的值
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
for i in np.nditer(a,op_flags=['readwrite']):
i*=2
print(a)
'''
输出为:
[[ 2 4 6]
[ 8 10 12]]
'''
倘若不改变op_flags的值,而直接改变数组元素的值,系统会报错
外部循环
nditer类的构造器拥有flags参数,它可以接受下列值:
参数 | 描述 |
---|---|
c_index | 可以跟踪 C 顺序的索引 |
f_index | 可以跟踪 Fortran 顺序的索引 |
multi-index | 每次迭代可以跟踪一种索引类型 |
external_loop | 给出的值是具有多个值的一维数组,而不是零维数组 |
例
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(a, flags = ['external_loop']):
print (x )
'''
输出为:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[ 0 5 10 15 20 25 30 35 40 45 50 55]
'''
广播迭代
如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。
例如:
import numpy as np
a = np.arange(0,60,5)
a=a.reshape(3,4)
b=np.array([1,2,3,4],dtype=int)
for i,j in np.nditer([a,b]):
print("%d+%d=%d" % (i,j,i+j))
'''
输出为:
0+1=1
5+2=7
10+3=13
15+4=19
20+1=21
25+2=27
30+3=33
35+4=39
40+1=41
45+2=47
50+3=53
55+4=59
'''
巴山夜雨涨秋池