Python数据科学手册:NumPy数组基础操作详解
引言
在Python数据科学领域,NumPy数组操作几乎等同于数据操作本身。作为Python科学计算的基础包,NumPy提供了高效的多维数组对象和丰富的数组操作方法。本文将深入探讨NumPy数组的基础操作,包括数组属性、索引、切片、重塑以及连接与分割等核心概念。
数组的基本属性
理解NumPy数组的属性是操作数组的第一步。让我们先创建几个不同维度的随机数组:
import numpy as np
rng = np.random.default_rng(seed=1701) # 设置随机种子保证结果可复现
# 创建不同维度的数组
x1 = rng.integers(10, size=6) # 一维数组
x2 = rng.integers(10, size=(3, 4)) # 二维数组
x3 = rng.integers(10, size=(3, 4, 5)) # 三维数组
每个NumPy数组都有几个关键属性:
ndim
: 数组的维度数shape
: 每个维度的大小(形状)size
: 数组元素的总数dtype
: 数组元素的数据类型
print("x3 ndim: ", x3.ndim) # 输出: 3
print("x3 shape:", x3.shape) # 输出: (3, 4, 5)
print("x3 size: ", x3.size) # 输出: 60
print("dtype: ", x3.dtype) # 输出: int64
理解这些属性对于后续的数组操作至关重要,特别是在处理高维数据时。
数组索引:访问单个元素
NumPy数组的索引方式与Python列表类似,但功能更加强大。
一维数组索引
x1 = np.array([9, 4, 0, 3, 8, 6])
print(x1[0]) # 输出第一个元素: 9
print(x1[4]) # 输出第五个元素: 8
print(x1[-1]) # 输出最后一个元素: 6
print(x1[-2]) # 输出倒数第二个元素: 8
多维数组索引
对于多维数组,使用逗号分隔的索引元组:
x2 = np.array([[3, 1, 3, 7],
[4, 0, 2, 3],
[0, 0, 6, 9]])
print(x2[0, 0]) # 输出第一行第一列元素: 3
print(x2[2, 0]) # 输出第三行第一列元素: 0
print(x2[2, -1]) # 输出第三行最后一列元素: 9
修改数组元素
通过索引可以直接修改数组元素:
x2[0, 0] = 12
print(x2)
# 输出:
# [[12 1 3 7]
# [ 4 0 2 3]
# [ 0 0 6 9]]
需要注意的是,NumPy数组有固定的数据类型。如果尝试将浮点数赋给整数数组,值会被截断:
x1[0] = 3.14159 # 会被截断为3
print(x1[0]) # 输出: 3
数组切片:访问子数组
切片是NumPy中非常强大的功能,可以高效地访问数组的子集。
一维数组切片
基本切片语法:x[start:stop:step]
print(x1[:3]) # 前三个元素: [3 4 0]
print(x1[3:]) # 索引3之后的元素: [3 8 6]
print(x1[1:4]) # 中间子数组: [4 0 3]
print(x1[::2]) # 每隔一个元素: [3 0 8]
print(x1[1::2]) # 从索引1开始每隔一个元素: [4 3 6]
负步长可以反转数组:
print(x1[::-1]) # 反转数组: [6 8 3 0 4 3]
print(x1[4::-2]) # 从索引4开始反向每隔一个元素: [8 0 3]
多维数组切片
多维数组切片使用逗号分隔不同维度的切片:
print(x2[:2, :3]) # 前两行前三列
# 输出:
# [[12 1 3]
# [ 4 0 2]]
print(x2[:3, ::2]) # 所有行,每隔一列
# 输出:
# [[12 3]
# [ 4 2]
# [ 0 6]]
print(x2[::-1, ::-1]) # 反转行和列
# 输出:
# [[ 9 6 0 0]
# [ 3 2 0 4]
# [ 7 3 1 12]]
访问行和列
获取单独的行或列是常见操作:
print(x2[:, 0]) # 第一列: [12 4 0]
print(x2[0, :]) # 第一行: [12 1 3 7]
print(x2[0]) # 简写形式,等同于x2[0, :]
视图与副本的重要区别
NumPy切片的一个关键特性是它返回的是原始数组的视图(view)而非副本(copy)。这意味着修改切片会影响原始数组:
x2_sub = x2[:2, :2]
x2_sub[0, 0] = 99
print(x2)
# 输出:
# [[99 1 3 7]
# [ 4 0 2 3]
# [ 0 0 6 9]]
如果需要独立的副本,可以显式调用copy()
方法:
x2_sub_copy = x2[:2, :2].copy()
x2_sub_copy[0, 0] = 42
print(x2) # x2不会被修改
总结
本文详细介绍了NumPy数组的基础操作,包括:
- 数组属性的理解与访问
- 单元素和多维数组的索引方法
- 一维和多维数组的切片技巧
- 视图与副本的关键区别
掌握这些基础操作是进行更复杂数据操作的前提。NumPy的高效性很大程度上来自于这些精心设计的数组操作方式,理解它们将帮助您写出更高效的数据处理代码。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考