Numpy 学习专题(二)—— 索引与切片

前言

  • 索引指的是用方括号 “[ ]” 加序号的形式引用数组中特定位置的元素,它的作用是从数组中取出一部分相应的元素重新组成一个子数组,而这个子数组就是通过索引得到的切片。

一、副本与视图

  • 在Numpy中做数组运算时,返回的结果只有两种,一是“视图”,二是“副本”。
import numpy as np
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
y = x  # 创建视图
y[0] = -1
print(x)
# [-1  2  3  4  5  6  7  8]
print(y)
# [-1  2  3  4  5  6  7  8]
# 此处改变视图y,原数组x也随之改变

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
y = x.copy()  # 创建副本
y[0] = -1
print(x)
# [1 2 3 4 5 6 7 8]
print(y)
# [-1  2  3  4  5  6  7  8]
# 此处改变副本y,原数组x不变
  • 从上例可知,对副本数据进行修改,不会影响到原始数据,这是因为他们物理内存不在同一位置;而对视图数据进行修改,原始数据也会随之改变,这是因为视图数据与原始数据物理内存在同一位置。
  • 此处用到了一个函数:numpy.copy()其作用就是为原始数据创建一个副本。

二、索引与切片

1.整数索引

  • 获取数组的单个元素,多维数组的子数组。
import numpy as np
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
print(x[6])  # 7

x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [12, 34, 56, 78, 99],
              [31, 32, 33, 34, 35]])
print(x[1])  # [16, 17, 18, 19, 20]
print(x[3][2])  # 33
print(x[3, 2])  # 33

2.切片索引

  • 切片即从数组中抽取一部分元素组成新的数组。
  • 对Python 列表 进行切片操作,得到的数组是原数组的 副本,即修改切片后,原数组不变。
  • 对Numpy数据进行切片操作,得到的数组是指向相同缓冲区的 视图
  • 一维数组
import numpy as np

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])

# 起始位置索引为1,结束位置索引为5,间隔为2
print(x[1:5:2])  # [2 4]

# 若不写间隔,则默认为1
print(x[0:4])  # [1 2 3 4]

# 若不写结束位置索引,则默认为最大索引值
print(x[2:])  # [3 4 5 6 7 8]

# 若不写起始位置索引,则默认为0
print(x[:2])  # [1 2]

# 若起始、结束位置索引均不写,则取全部
print(x[:])  # [1 2 3 4 5 6 7 8]

# 若索引值为负,则最大索引值为-1,依次向前递减
print(x[-2:])  # [7 8]
print(x[:-2])  # [1 2 3 4 5 6]

# 利用负数下标翻转数组
print(x[::-1])  # [8 7 6 5 4 3 2 1]
  • 二维数组,切片的第一片定义了行的切片,第二片定义了列的切片。
import numpy as np
x = np.array([[1, 2, 3, 4, 5],
              [6, 7, 8, 9, 10],
              [11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25]])

print(x[2:4])
# [[11 12 13 14 15]
#  [16 17 18 19 20]]

print(x[1:5:2])
# [[6 7 8 9 10]
#  [16, 17, 18, 19, 20]]

print(x[2:])
# [[11, 12, 13, 14, 15],
# [16, 17, 18, 19, 20],
# [21, 22, 23, 24, 25]]

print(x[:2])
# [[11 12 13 14 15]
#  [16 17 18 19 20]]

print(x[-2:])
# [[16, 17, 18, 19, 20],
# [21, 22, 23, 24, 25]]

print(x[:-2])
# [[1, 2, 3, 4, 5],
#[6, 7, 8, 9, 10],
# [11, 12, 13, 14, 15]]

print(x[:])
# [[1 2 3 4 5]
#  [6 7 8 9 10]
#  [11 12 13 14 15]
#  [16 17 18 19 20]
#  [21 22 23 24 25]]

# 输出第二行数据
print(x[1, :]) # [6 7 8 9 10]

# 输出第二列数据
print(x[:, 1]) # [2 7 12 17 22]

# 输出第1行,第2到4个数据
print(x[0, 1:4])  # [2 3 4]

# 输出第1列,第2到4个数据
print(x[1:4, 0]) # [6 11 16]

print(x[1:3, 2:4])
# [[8 9]
#  [13 14]]

print(x[:, :]) # 效果与x[:]一样

# 行,列,间隔均为2
print(x[::2, ::2])
# [[1 3 5]
#  [11 13 15]
#  [21 23 25]]

# 从0行开始,间隔2行赋值;从1列开始,间隔3列赋值
x[0::2, 1::3] = 0
print(x)
# [[1  0 3 4  0]
#  [6 7 8 9 10]
#  [11  0 13 14  0]
#  [16 17 18 19 20]
#  [21  0 23 24  0]]

# 所有行颠倒顺序
print(x[::-1, :])

# 所有列颠倒顺序
print(x[:, ::-1])

3.整数数组索引

  • 方括号内传入多个索引值,可以同时选择多个元素。
  • 一维数组:
import numpy as np 

# 从一维数组中抽取特殊点
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
r = [0, 1, -1]
print(x[r])  # [1 2 8]

# 从一维数组中抽取特殊点组成二维数组
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
r = np.array([[0, 1], [3, 4], [6, 7])
print(x[r])
# [[1 2]
#  [4 5]
#  [7 8]]
  • 二维数组
# 从二维数组中抽取特殊行
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, -1]
print(x[r])
# [[11 12 13 14 15]
#  [16 17 18 19 20]
#  [31 32 33 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]])
r = np.array([[0, 1], [3, 4]])
print(x[r])
# [[[11 12 13 14 15]
#   [16 17 18 19 20]]
#
#  [[26 27 28 29 30]
#   [31 32 33 34 35]]]

# 从二维数组中抽取特殊点组成一维数组
r = [0, 1, 2]
c = [2, 3, 4]
y = x[r, c]  # r,c均为一维数组,故y也为一维数组
print(y)  # [13 19 25]

# 从二维数组中抽取特殊点组成二维数组
r = np.array([[0, 0], [4, 4]])
c = np.array([[0, 4], [0, 4]])
y = x[r, c]  # r,c均为二维数组,故y也为二维数组
print(y)
# [[11 15]
#  [31 35]]
  • 特殊函数numpy.take()
import numpy as np

# 一维数组
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
r = [0, 1, 2]
print(np.take(x, r))  # [1 2 3]

# 二维数组
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]
print(np.take(x, r, axis=0))  # 输出特定行
# [[11 12 13 14 15]
#  [16 17 18 19 20]
#  [21 22 23 24 25]]
print(np.take(x, r, axis=1))  # 输出特定列
# [[11 12 13]
#  [16 17 18]
#  [21 22 23]
#  [26 27 28]
#  [31 32 33]]

4.布尔索引

import numpy as np

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
y = x > 5
print(y)  # [False False False False False  True  True  True]
print(x[x > 5])  # [6 7 8]

x = np.array([1, 9, np.nan, 3, 4, np.nan, 0])
y = np.logical_not(np.isnan(x))  # 逻辑非
print(x[y])  # [1. 9. 3. 4. 0.]

# 二维数组变一维数组
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 > 25
print(y)
# [[False False False False False]
#  [False False False False False]
#  [False False False False False]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]]
print(x[x > 25])
# [26 27 28 29 30 31 32 33 34 35]

三、补充知识

1.数组迭代

  • 本块介绍函数np.apply_along_axis()
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 = np.apply_along_axis(np.sum, 0, x)
print(y)  # [105 110 115 120 125]

# 每行求和
y = np.apply_along_axis(np.sum, 1, x)
print(y)  # [ 65  90 115 140 165]

# 每列求平均
y = np.apply_along_axis(np.mean, 0, x)
print(y)  # [21. 22. 23. 24. 25.]

# 每行求平均
y = np.apply_along_axis(np.mean, 1, x)
print(y)  # [13. 18. 23. 28. 33.]

2.array换行、换列

import numpy as np

A = np.arange(9).reshape(3, 3)
print(A)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

# 列列互换
B = A[:, [2, 1, 0]]
print(B)
# [[2 1 0]
#  [5 4 3]
#  [8 7 6]]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值