numpy-索引和遍历
索引和遍历
NumPy 的切片创建了 view 而不是像内置的python序列(如string、tuple和list)那样的副本。在从大型数组中提取一小部分时必须小心,因为提取的小部分包含对大型原始数组的引用,在对其派生的所有数组进行垃圾收集之前,不会释放这些数组的内存。在这种情况下, copy()
建议使用。
- 当切片的数量少于数组维度时,缺失的维度索引被认为是一个完整切片, 省略与使用“:”或“…”等价
基础索引
一维数组
一维数组的索引和 Python 中 list 结构索引十分相似,需要注意在切片索引的时候末尾的下标是取不到
a = np.array([0, 1, 2, 3, 4, 5])
print(type(a))
print(a[0]) # 0
print(a[2:4]) # [2 3]
print(a[1:3]) # [1 2]
print(a[1:5:2]) # [1 3]
二维数组
切片和索引
a = np.arange(12).reshape(3, 4)
print(a[2][0]) #8
print(a[2,0]) #8
#第一种方式通过递归访问,首先a[2]将得到array([8, 9, 10, 11]),然后a[2][0]访问索引为0的数字,得到8;如果对数组的大小理解清楚了,那么第二种方式就是非常直接的指定了该数据在第0轴的索引2位置和第1轴的索引0位置。
a = np.array([[1,2,3,4,5],[6,7,8,9,10]])
print(a[0:1]) #截取第一行,返回 [[1 2 3 4 5]]
print(a[1,2:5]) #截取第二行,第三、四、五列,返回 [8 9 10]
print(a[1,:]) #截取第二行,返回 [ 6 7 8 9 10]
不同行,采用 , 隔开
同一行满足列表索引规则
arr_2d = np.arange(16).reshape(4,4)
print(arr_2d)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]]
print(arr_2d[0, 1:3])
print(arr_2d[0:2, 1:3])
# [1 2]
# [[1 2]
# [5 6]]
print(arr_2d[:, 1:3])
#[[ 1 2]
# [ 5 6]
# [ 9 10]
# [13 14]]
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
# 第2列元素
print(a[...,1])
# 第2行元素
print(a[1,...])
# 第2列及剩下的所有元素
print(a[...,1:])
#[2 4 5]
#[3 4 5]
#[[2 3]
# [4 5]
# [5 6]]
高级索引
使用索引数组进行索引
a = np.arange(5,16)
print(a[[0, 1]]) # [5 6]
print(a[np.array([[0, 1]])]) # [[5 6]]
print(a[np.array([[0, 1], [2, 3]])]) # [[5 6] [7 8]]
#---------------------------------------------------------------
#取值矩阵的四个角
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x)
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
print(y)
#[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
#[[ 0 2]
# [ 9 11]]
使用布尔值数组进行索引
#获取大于 5 的元素
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x)
# 现在我们会打印出大于 5 的元素
print(x[x>5])
#[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
#[ 6 7 8 9 10 11]
#---------------------------------------------------------------
zarten = np.random.randn(5,4)
print(zarten)
print('')
zarten_bool = np.array([True, False, False, False, True])
print(zarten[zarten_bool])
#[[0.12370779 0.60020841]
# [0.19022537 0.65618376]
# [0.5231678 0.18813379]
# [0.53643122 0.26875578]
# [0.55525969 0.23672487]]
#[[0.12370779 0.60020841]
# [0.55525969 0.23672487]]
zarten_1 = np.array(['A', 'B', 'C', 'D', 'A'])
print(zarten[zarten_1 == 'A']) # != 不等于,& 与运算,| 或运算
#[[0.12370779 0.60020841]
# [0.55525969 0.23672487]]
#---------------------------------------------------------------
#~(取反运算符)来过滤 NaN
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print(a[~np.isnan(a)])
#---------------------------------------------------------------
a = np.array(['www', 'finthon', 'com'])
b = np.arange(12).reshape(3, 4)
print(b[a == 'finthon'])
#[[4 5 6 7]]
花式索引
是利用整数数组进行行索引的方式
a = np.arange(12).reshape(3, 4)
print(a)
b = a[[2, 0, 1]] # 一维整数数组, 针对的是 0 维度
print(b)
#[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#[[ 8 9 10 11]
# [ 0 1 2 3]
# [ 4 5 6 7]]
c=a[[1, 1, 2, 2], [1, 3, 0, 2]] # 二维整数数组,针对的是两个维度
print(c)
# [ 5 7 8 10]
np.ix_()
函数
np.ix_()
函数,能把两个一维数组 转换为 一个用于选取方形区域的索引器
a = np.arange(10).reshape(2, 5)
b=a[[0,1],[2,4]] #整数数组索引
c=a[np.ix_([0, 1], [2, 4])] #np.ix_() 整数数组索引
print(b)
print(c)
#[2 9]
#[[2 4]
# [7 9]]
d=a[[True, True], [2, 4]]
e=a[np.ix_([True, True], [2, 4])]
print(d)
print(e)
#[2 9]
#[[2 4]
# [7 9]]
np.where()
np.where(condition, [x, y])
必写参数是condition(判断条件),后边的x和y是可选参数
-
当where内只有一个参数时,那个参数表示条件,当条件成立时,where返回的是每个符合condition条件元素的坐标,返回的是以元组的形式
-
当where内有三个参数时,第一个参数表示条件,当条件成立时where方法返回x,当条件不成立时where返回y
其实你不应该在这个目录分区里
a = np.array([2, 4, 6, 8, 10])
print(a)
print(np.where(a > 5))
print(a[np.where(a > 5)])
#[ 2 4 6 8 10]
#(array([2, 3, 4], dtype=int64),)
#[ 6 8 10]
#---------------------------------------------------------------
x= np.random.randint(0,4,size=(3,3))
print(x)
print(np.where(x>2))
#[[0 2 1]
# [0 1 3]
# [3 1 0]]
#(array([1, 2], dtype=int64), array([2, 0], dtype=int64))
print(np.where(x==2))
(array([0], dtype=int64), array([1], dtype=int64))
#---------------------------------------------------------------
a = np.arange(10)
print(a)
aa = np.where(a, 1, -1)
print(aa)
aaa = np.where(a > 5, 5, -5)
print(aaa)
#[0 1 2 3 4 5 6 7 8 9]
#[-1 1 1 1 1 1 1 1 1 1]
#[-5 -5 -5 -5 -5 -5 5 5 5 5]
Numpy数组遍历
按照内存布局打印数组元素
numpy.nditer
迭代器返回的元素顺序,是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先
arr = np.arange(6).reshape(2,3)
for i in np.nditer(arr):
print(i, end=" ")
#0 1 2 3 4 5
#---------------------------------------------------------------
#默认的打印顺序是行序优先 order="C"
for i in np.nditer(arr.T):
print(i, end=" ")
#0 1 2 3 4 5
#控制遍历顺序
print ('以 F 风格顺序排序:')
for i in np.nditer(arr, order="F"):
print(i, end=" ")
# 可选参数 op_flags 默认 迭代遍历的数组为只读对象(read-only)
arr1 = np.arange(8).reshape(2,4)
for i in np.nditer(arr1, op_flags=["readwrite"]):
i[...] = i**2
#[[ 0 1 4 9]
# [16 25 36 49]]
# flags 参数可以接受传入一个数组或元组,它可以接受下列值
参数 | 描述 |
---|---|
c_index | 可以跟踪 C 顺序的索引 |
f_index | 可以跟踪 Fortran 顺序的索引 |
multi-index | 每次迭代可以跟踪多重索引类型 |
external_loop | 给出的值是具有多个值的一维数组,而不是零维数组 |
#设置 flags=["c_index"],可以实现类似 list 的 enumerate 函数的效果
cit = np.nditer(arr, flags=["c_index"])
while not cit.finished:
print("value:", cit[0], "index:<{}>".format(cit.index))
cit.iternext()
# value: 0 index:<0>
# value: 1 index:<1>
# value: 2 index:<2>
# value: 3 index:<3>
# value: 4 index:<4>
# value: 5 index:<5>
# value: 6 index:<6>
# value: 7 index:<7>
#---------------------------------------------------------------
mul_it = np.nditer(arr, flags=['multi_index'])
while not mul_it.finished:
print("value:", mul_it[0], "index:<{}>".format(mul_it.multi_index))
mul_it.iternext()
# value: 0 index:<(0, 0)>
# value: 1 index:<(0, 1)>
# value: 2 index:<(0, 2)>
# value: 3 index:<(0, 3)>
# value: 4 index:<(1, 0)>
# value: 5 index:<(1, 1)>
# value: 6 index:<(1, 2)>
# value: 7 index:<(1, 3)>