DW-numpy_索引、切片与迭代

本文介绍了NumPy中数组的索引、切片和迭代操作。切片通常返回原数组的视图,而整数数组索引则创建副本。布尔索引允许根据条件选取元素。此外,还讲解了如何使用`apply_along_axis`函数进行数组遍历。
摘要由CSDN通过智能技术生成

副本与视图

在 Numpy 中,返回结果是 副本 或者 视图

  • 赋值运算:不会为数组和数组中的任何元素创建副本。(是同一个,故同时变化)

  • numpy.ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据。

  • 数组切片操作返回的对象只是原数组的视图。

import numpy as np

x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])
y = x
y[::2, :3:2] = -1
print(x)
# [[-1 12 -1 14 15]
#  [16 17 18 19 20]
#  [-1 22 -1 24 25]
#  [26 27 28 29 30]
#  [-1 32 -1 34 35]]
print(y)
# [[-1 12 -1 14 15]
#  [16 17 18 19 20]
#  [-1 22 -1 24 25]
#  [26 27 28 29 30]
#  [-1 32 -1 34 35]]

x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])
y = x.copy()
y[::2, :3:2] = -1
print(x)
# [[11 12 13 14 15]
#  [16 17 18 19 20]
#  [21 22 23 24 25]
#  [26 27 28 29 30]
#  [31 32 33 34 35]]
print(y)
# [[-1 12 -1 14 15]
#  [16 17 18 19 20]
#  [-1 22 -1 24 25]
#  [26 27 28 29 30]
#  [-1 32 -1 34 35]]

索引与切片

数组索引机制指的是用方括号([])加序号的形式引用单个数组元素,它的用处很多,比如抽取元素,选取数组的几个元素,甚至为其赋一个新值。

切片索引:

  • 对 python 列表进行切片操作得到的数组是原数组的副本,而对 Numpy 数据进行切片操作得到的数组则是指向相同缓冲区的视图
  • x[i];
    x[i][j]等价于 x[i,j])
  • x[ start:stop:step,start:stop:step ]切片索引,逗号前是行,后面是列;下表从0开始,省去表示默认从第0个数字开始;为左开右闭;-1表示最后一个元素。
#利用负数下标翻转数组
print(x[::-1])  # [8 7 6 5 4 3 2 1]

dots 索引

...表示足够多的冒号来构建完整的索引列表。

比如,如果 x 是 5 维数组:

  • x[1,2,...] 等于 x[1,2,:,:,:]
  • x[...,3] 等于 x[:,:,:,:,3]
  • x[4,...,5,:] 等于 x[4,:,:,5,:]
import numpy as np
x = np.random.randint(1, 100, [2, 2, 3])
print(x)
# [[[ 5 64 75]
#   [57 27 31]]
# 
#  [[68 85  3]
#   [93 26 25]]]

print(x[1, ...])
# [[68 85  3]
#  [93 26 25]]

print(x[..., 2])
# [[75 31]
#  [ 3 25]]

整数数组索引

注意!

  • x[r, c]:r和c都是数组,表示行和列,表示的是对应坐标(r和c是一一对应)

  • x[r]:r若为高维数组,表示的是这个输出的数组形状,但是r仍然只表示行。

  • numpy. take(a, indices, axis=None, out=None, mode='raise') Take elements from an array along an axis. axis=0按行取

  • np.take(x, [r, c],axis=0/1) 存疑

  • 应注意:使用切片索引(视图),生成的数组视图将始终是原始数组的子数组,
    但是整数数组索引(副本),不是其子数组,是形成新的数组

x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])
r = [0, 1, 2]
c = [2, 3, 4]
y = x[r, c]
print(y)
# [13 19 25]
x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])

r = np.array([[0, 1], [3, 4]])
print(x[r])
#等价于print(np.take(x, r, axis=0))
# [[[11 12 13 14 15]
#   [16 17 18 19 20]]
#
#  [[26 27 28 29 30]
#   [31 32 33 34 35]]]

# 获取了 5X5 数组中的四个角的元素。
# 行索引是 [0,0] 和 [4,4],而列索引是 [0,4] 和 [0,4]。
r = np.array([[0, 0], [4, 4]])
c = np.array([[0, 4], [4, 0]])
y = x[r, c]
print(y)
# [[11 15]
#  [35 31]]
#????????????????????????????????????好奇怪啊 咋来的
x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])
r = [0, 1, 2]
c = [2, 3, 4]
y = np.take(x, [r, c])
print(y)
# [[11 12 13]
#  [13 14 15]]
#副本和视图问题:
#切片索引与整数数组索引
import numpy as np

a=np.array([[1,2],[3,4],[5,6]])
b=a[0:1,0:1]
b[0,0]=2
print(a[0,0]==b)
#[[True]]

b=a[0,0]
b=2
print(a[0,0]==b)
#False

布尔索引:

通过一个布尔数组来索引目标数组。

  • x[x>5]:取出大于5的数(x>5的返回布尔数组,x[布尔数组]将布尔数组中的True的位置的值返回
  • logical_not(布尔数组):非运算,True改为False
  • np.logical_and(express1, express2) #逻辑与:同时成立
x = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
y = np.logical_not(np.isnan(x))
print(x[y])
# [1. 2. 3. 4. 5.]
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 50)
y = np.sin(x)  #都是数组
# print(len(x))  # 50
plt.plot(x, y)

mask = y >= 0 #返回一个布尔数组
'''
[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True False False False False False False False False False False False
 False False False False False False False False False False False False
 False False]
'''
# print(len(x[mask]))  #x[mask]取出布尔数组中为True的值  25

plt.plot(x[mask], y[mask], 'bo')

mask = np.logical_and(y >= 0, x <= np.pi / 2) #逻辑与:同时成立
'''
[ True  True  True  True  True  True  True  True  True  True  True  True
  True False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False]
'''

plt.plot(x[mask], y[mask], 'go')
plt.show()

在这里插入图片描述

数组迭代

除了for循环,Numpy 还提供另外一种更为优雅的遍历方法。

  • apply_along_axis(func1d, axis, arr) Apply a function to 1-D slices along the given axis.
  • axis=0沿着列计算,axis=1沿着行计算
x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])

y = np.apply_along_axis(np.sum, 0, x) #沿着列计算
print(y)  # [105 110 115 120 125]


def my_func(x):
    return (x[0] + x[-1]) * 0.5

y = np.apply_along_axis(my_func, 1, x)
print(y)  #[13. 18. 23. 28. 33.]

交换(反转)二维数组中的两列(行)

#索引和切片
arr = np.arange(9).reshape(3, 3)
x = arr[:, [2, 1, 0]]
print(x)
# [[2 1 0]
#  [5 4 3]
#  [8 7 6]]

x = arr[::-1, :]
print(x)
# [[6 7 8]
#  [3 4 5]
#  [0 1 2]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值