NumPy完全指南:从数组操作到文件读写的实战技巧
1. 一维数组切片操作:精准数据提取的艺术
在数据分析中,数组切片是最基础也是最核心的操作之一。掌握切片技巧能够让你高效地提取所需数据。
基本语法与示例
import numpy as np
# 创建示例数组
aArray = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print("原数组:", aArray)
print("aArray[2:4]:", aArray[2:4]) # 选取第3、4个元素(索引2、3)
print("aArray[0:5:2]:", aArray[0:5:2]) # 选取第1、3、5个元素(步长2)
print("aArray[::-1]:", aArray[::-1]) # 数组反转
运行结果
原数组: [0 1 2 3 4 5 6 7 8 9]
aArray[2:4]: [2 3]
aArray[0:5:2]: [0 2 4]
aArray[::-1]: [9 8 7 6 5 4 3 2 1 0]
实用技巧
- 负索引:
aArray[-3:]获取最后三个元素 - 省略开始/结束:
aArray[:5]获取前5个元素,aArray[5:]获取第6个及之后元素 - 步长为负:实现数组反转
2. 二维数组操作:矩阵数据处理的核心
二维数组是处理表格数据、图像数据等的关键数据结构。
创建与基本操作
# 创建二维数组
A = np.array([1, 2, 3])
B = np.array([4, 5, 6])
C = np.array([7, 8, 9])
X = np.array([A, B, C]) # 3×3二维数组
print("二维数组X:\n", X)
print("数组形状:", X.shape)
元素选取与切片
print("X[1, 2]:", X[1, 2]) # 第2行第3列元素
print("行切片X[1:3, :]:\n", X[1:3, :]) # 第2-3行所有列
print("列切片X[:, 0:2]:\n", X[:, 0:2]) # 所有行第1-2列
运行结果
二维数组X:
[[1 2 3]
[4 5 6]
[7 8 9]]
数组形状: (3, 3)
X[1, 2]: 6
行切片X[1:3, :]:
[[4 5 6]
[7 8 9]]
列切片X[:, 0:2]:
[[1 2]
[4 5]
[7 8]]
3. 数组形状修改:灵活调整数据维度
在实际应用中,经常需要改变数组的形状以适应不同的算法需求。
reshape方法详解
# 创建一维数组
A = np.arange(12)
print("原数组A:", A)
# 重塑为3×4数组
B = A.reshape(3, 4)
print("重塑后的B:\n", B)
# 验证数据共享
B[0, 0] = 100
print("修改B后A的值:", A[0]) # A也会被修改
降维操作比较
# ravel() vs flatten()
A = np.array([[1, 2], [3, 4]])
ravel_view = A.ravel()
flatten_copy = A.flatten()
print("原数组A:\n", A)
print("ravel结果:", ravel_view)
print("flatten结果:", flatten_copy)
# 修改视图测试
ravel_view[0] = 100
print("修改ravel后A:\n", A) # A被修改
flatten_copy[0] = 999
print("修改flatten后A:\n", A) # A不变
4. 数组转置与高级操作
转置操作在矩阵运算和数据分析中极为重要。
转置方法
# 创建非对称数组
A = np.arange(12).reshape(3, 4)
print("原数组A(3×4):\n", A)
# 两种转置方法
B1 = A.transpose()
B2 = A.T
print("转置后B1(4×3):\n", B1)
print("转置后B2(4×3):\n", B2)
高维数组转置
# 三维数组转置
C = np.arange(24).reshape(2, 3, 4)
print("三维数组形状:", C.shape)
# 指定轴顺序转置
D = C.transpose(1, 0, 2)
print("转置后形状:", D.shape)
5. 数组排序与统计:数据分析的基础
排序和统计是数据分析中最常用的操作。
排序操作
# 创建随机数组
np.random.seed(42)
data = np.random.randint(0, 100, 10)
print("原始数据:", data)
# 排序
sorted_data = np.sort(data)
print("排序后:", sorted_data)
# 二维数组按轴排序
matrix = np.random.randint(0, 50, (3, 5))
print("原始矩阵:\n", matrix)
print("按行排序:\n", np.sort(matrix, axis=1))
print("按列排序:\n", np.sort(matrix, axis=0))
统计方法应用
# 创建示例数据
scores = np.array([85, 92, 78, 90, 88, 76, 95, 89, 84, 91])
print("成绩数据:", scores)
print("总和:", np.sum(scores))
print("平均值:", np.mean(scores))
print("标准差:", np.std(scores))
print("最大值:", np.max(scores), "位置:", np.argmax(scores))
print("最小值:", np.min(scores), "位置:", np.argmin(scores))
运行结果
成绩数据: [85 92 78 90 88 76 95 89 84 91]
总和: 868
平均值: 86.8
标准差: 5.768
最大值: 95 位置: 6
最小值: 76 位置: 5
6. 数组类型转换与视图操作
正确处理数据类型和视图关系是避免bug的关键。
类型转换
# 创建浮点数数组
float_array = np.array([1.2, 2.7, 3.1, 4.8])
print("浮点数组:", float_array, "类型:", float_array.dtype)
# 转换为整数
int_array = float_array.astype(np.int32)
print("整型数组:", int_array, "类型:", int_array.dtype)
# 注意:小数部分被截断,不是四舍五入
视图与副本深度解析
# 创建原始数组
original = np.array([[1, 2], [3, 4]])
# 创建视图和副本
view_array = original.view()
copy_array = original.copy()
print("原数组:", original)
print("视图:", view_array)
print("副本:", copy_array)
# 修改测试
print("\n--- 修改视图 ---")
view_array[0, 0] = 100
print("原数组:", original) # 被修改
print("视图:", view_array) # 被修改
print("副本:", copy_array) # 不变
print("\n--- 修改副本 ---")
copy_array[0, 0] = 999
print("原数组:", original) # 不变
print("视图:", view_array) # 不变(但之前已被修改)
print("副本:", copy_array) # 被修改
7. 条件筛选:智能数据提取
条件筛选让我们能够基于特定条件提取数据。
基本条件筛选
# 创建数据
data = np.array([12, 25, 8, 17, 32, 5, 21, 14])
# 简单条件筛选
print("大于15的元素:", data[data > 15])
print("偶数元素:", data[data % 2 == 0])
# 多条件组合
condition = (data > 10) & (data < 20)
print("10到20之间的元素:", data[condition])
compress方法应用
# 使用compress进行条件筛选
data = np.array([1, 2, 3, 4, 5, 6])
# 布尔条件
bool_condition = [True, False, True, False, True, False]
result1 = np.compress(bool_condition, data)
print("布尔条件筛选:", result1)
# 索引数组
index_condition = [0, 2, 4] # 选择第1、3、5个元素
result2 = np.compress(index_condition, data, axis=0)
print("索引条件筛选:", result2)
8. 数组拼接:数据整合的艺术
数据拼接是将多个数据集合并的重要技术。
水平与垂直拼接
# 创建示例数组
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = np.array([[9, 10]])
print("数组A:\n", A)
print("数组B:\n", B)
print("数组C:\n", C)
# 水平拼接
horizontal = np.hstack([A, B])
print("水平拼接:\n", horizontal)
# 垂直拼接
vertical = np.vstack([A, C])
print("垂直拼接:\n", vertical)
# 使用concatenate
concat_h = np.concatenate([A, B], axis=1)
concat_v = np.concatenate([A, C], axis=0)
print("concatenate水平:\n", concat_h)
print("concatenate垂直:\n", concat_v)
运行结果
数组A:
[[1 2]
[3 4]]
数组B:
[[5 6]
[7 8]]
数组C:
[[9 10]]
水平拼接:
[[1 2 5 6]
[3 4 7 8]]
垂直拼接:
[[ 1 2]
[ 3 4]
[ 9 10]]
9. 数组分割:大数据集处理的利器
分割操作让我们能够将大数据集分解为更易处理的小块。
分割方法详解
# 创建大型数组
big_array = np.arange(24).reshape(4, 6)
print("原始数组:\n", big_array)
# 水平分割
horizontal_parts = np.hsplit(big_array, 3) # 分成3部分
print("\n水平分割为3部分:")
for i, part in enumerate(horizontal_parts):
print(f"第{i+1}部分:\n{part}")
# 垂直分割
vertical_parts = np.vsplit(big_array, 2) # 分成2部分
print("\n垂直分割为2部分:")
for i, part in enumerate(vertical_parts):
print(f"第{i+1}部分:\n{part}")
不均匀分割
# 按指定位置分割
array = np.arange(10)
print("原数组:", array)
# 在索引3和7处分割
split_parts = np.split(array, [3, 7])
print("在索引3和7处分割:")
for i, part in enumerate(split_parts):
print(f"第{i+1}段: {part}")
10. NumPy文件读写:数据持久化实战
文件读写是数据科学工作流中的重要环节。
文本文件读写
# 创建示例数据
data = np.array([[1.5, 2.3, 3.7],
[4.1, 5.9, 6.2],
[7.8, 8.4, 9.0]])
print("原始数据:\n", data)
# 保存到CSV文件
np.savetxt('data.csv', data,
delimiter=',',
fmt='%.2f',
header='Column1,Column2,Column3',
comments='# ')
print("数据已保存到data.csv")
# 从CSV文件读取
loaded_data = np.loadtxt('data.csv', delimiter=',')
print("从文件读取的数据:\n", loaded_data)
高级文件操作
# 带缺失值的文件读取
# 创建含缺失值的示例文件
with open('data_with_missing.csv', 'w') as f:
f.write("1,2,3\n")
f.write("4,,6\n") # 第二行第二个值为空
f.write("7,8,9\n")
# 使用genfromtxt处理缺失值
data_with_missing = np.genfromtxt('data_with_missing.csv',
delimiter=',',
filling_values=0)
print("处理缺失值后的数据:\n", data_with_missing)
二进制文件操作
# 创建大型数组
large_data = np.random.rand(100, 50)
# 保存为二进制格式
np.save('large_data.npy', large_data)
# 读取二进制文件
loaded_binary = np.load('large_data.npy')
print("二进制文件形状:", loaded_binary.shape)
# 保存多个数组
array1 = np.arange(10)
array2 = np.ones((3, 3))
np.savez('multiple_arrays.npz', arr1=array1, arr2=array2)
# 读取多个数组
loaded_arrays = np.load('multiple_arrays.npz')
print("arr1:", loaded_arrays['arr1'])
print("arr2:", loaded_arrays['arr2'])
实战案例:完整的数据处理流程
让我们通过一个完整案例展示NumPy的强大功能。
import numpy as np
def data_processing_pipeline():
"""完整的数据处理流程示例"""
# 1. 生成模拟销售数据
np.random.seed(42)
sales_data = np.random.randint(100, 1000, (30, 4)) # 30天,4个产品
print("原始销售数据(前5行):\n", sales_data[:5])
# 2. 数据清洗:移除异常值(假设大于900为异常)
cleaned_data = sales_data[sales_data < 900]
cleaned_data = cleaned_data.reshape(-1, 4) # 重塑形状
print(f"\n数据清洗: 从{sales_data.shape[0]}行减少到{cleaned_data.shape[0]}行")
# 3. 数据统计
print("\n=== 数据统计 ===")
print("各产品平均销量:", np.mean(cleaned_data, axis=0))
print("各产品总销量:", np.sum(cleaned_data, axis=0))
print("销量最好的一天:", np.max(cleaned_data, axis=0))
# 4. 数据排序:按总销量排序
daily_totals = np.sum(cleaned_data, axis=1)
sorted_indices = np.argsort(daily_totals)[::-1] # 降序排列
sorted_data = cleaned_data[sorted_indices]
print("\n销量最好的5天:")
for i in range(5):
print(f"第{i+1}名: 总销量{daily_totals[sorted_indices[i]]}")
# 5. 保存处理结果
np.savetxt('processed_sales.csv', sorted_data,
delimiter=',', fmt='%d',
header='Product1,Product2,Product3,Product4')
print("\n处理完成!结果已保存到 processed_sales.csv")
# 运行示例
data_processing_pipeline()
总结
通过本指南,我们全面掌握了NumPy的核心功能:
- 基础操作:数组创建、索引、切片
- 形状管理:reshape、转置、拼接、分割
- 数据处理:排序、统计、条件筛选
- 类型系统:数据类型转换、视图与副本
- 文件操作:文本和二进制文件的读写
NumPy的这些功能为后续的Pandas数据分析、机器学习建模等高级应用奠定了坚实基础。掌握这些核心操作,你将能够高效处理各种数值计算任务。
关键要点记住:
- 切片操作是数据提取的基础
- 理解视图与副本的区别避免意外修改
- 合理选择文件格式平衡性能与可读性
- 善用统计方法快速了解数据特征
希望这份指南能帮助你在数据科学的道路上更进一步!