【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧2

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧

【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧1:https://developer.aliyun.com/article/1617470

4. NumPy常用函数

NumPy提供了许多内置的数学函数,可以用于数组的快速计算。

求和与均值
arr = np.array([1, 2, 3, 4, 5])
print(np.sum(arr))  # 求和
print(np.mean(arr))  # 求均值

输出:

15
3.0
最大值与最小值
print(np.max(arr))  # 最大值
print(np.min(arr))  # 最小值

输出:

5
1
累积和
print(np.cumsum(arr))  # 累积和

输出:

[ 1  3  6 10 15]
排序
arr = np.array([3, 1, 2, 5, 4])
sorted_arr = np.sort(arr)
print(sorted_arr)

输出:

[1 2 3 4 5]

第四部分:NumPy与矩阵操作

1. NumPy中的矩阵概念

在科学计算和工程应用中,矩阵是非常重要的工具。NumPy中的二维数组非常适合用于矩阵的表示和运算。虽然NumPy有专门的matrix对象,但通常推荐使用普通的二维数组ndarray,因为它更通用,且在大多数情况下能满足需求。

2. 矩阵的基本运算

矩阵乘法

矩阵乘法是矩阵运算中最基本的操作之一。NumPy提供了多种方法来进行矩阵乘法。

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

# 使用dot函数进行矩阵乘法
C = np.dot(A, B)
print(C)

输出:

[[19 22]
 [43 50]]

这里,我们使用np.dot()函数进行了矩阵乘法,结果是两个矩阵的标准矩阵乘积。

矩阵转置

矩阵转置是交换矩阵的行和列。

A = np.array([[1, 2], [3, 4]])
A_transposed = A.T
print(A_transposed)

输出:

[[1 3]
 [2 4]]
矩阵的逆

矩阵的逆在许多线性代数应用中都非常重要。NumPy可以使用np.linalg.inv()函数来计算矩阵的逆。

A = np.array([[1, 2], [3, 4]])
A_inv = np.linalg.inv(A)
print(A_inv)

输出:

[[-2.   1. ]
 [ 1.5 -0.5]]

注意,并不是所有矩阵都有逆矩阵,只有行列式非零的方阵才有逆矩阵。

矩阵行列式

行列式是矩阵的重要属性之一,尤其在求解线性方程组、特征值和特征向量时非常有用。我们可以使用np.linalg.det()函数来计算矩阵的行列式。

A = np.array([[1, 2], [3, 4]])
det_A = np.linalg.det(A)
print(det_A)

输出:

-2.0000000000000004

3. 广播机制(详细)

广播的原理

广播是指NumPy在算术运算中自动扩展较小的数组,使它们形状相同的过程。广播机制允许我们对不同形状的数组进行算术运算而不需要明确地复制数据。

广播的规则

广播遵循以下规则:

  1. 如果数组的维度不同,首先会在较小数组的左侧补充“1”使其维度与较大的数组相同。
  2. 接着,比较两个数组在每个维度上的大小,如果其中一个数组在某个维度的大小为1,则该数组可以在此维度上进行广播(扩展到与另一个数组相同的大小)。
  1. 如果在任何一个维度上,两个数组的大小都不相同且不为1,则不能进行广播,运算会报错。
广播实例
A = np.array([[1, 2, 3], [4, 5, 6]])
B = np.array([1, 0, 1])

C = A + B
print(C)

输出:

[[2 2 4]
 [5 5 7]]

在这个例子中,B被广播到与A相同的形状,即B的形状从(3,)变为(2, 3),从而进行加法运算。

4. NumPy的高级应用

向量化操作

向量化操作指的是将循环操作转化为数组操作,这样不仅简化了代码,还提高了计算效率。NumPy的核心优势之一就是高效的向量化运算。

arr = np.arange(1, 11)
squared = arr ** 2
print(squared)

输出:

[  1   4   9  16  25  36  49  64  81 100]
条件筛选与筛选赋值

NumPy允许我们根据条件筛选数组中的元素,并且可以直接对这些筛选出来的元素进行赋值操作。

arr = np.array([1, 2, 3, 4, 5])
arr[arr > 3] = 10
print(arr)

输出:

[ 1  2  3 10 10]

在这个例子中,arr > 3的条件筛选出了大于3的元素,然后这些元素被赋值为10。

NumPy的随机数生成

NumPy包含了一个强大的随机数生成器,可以用于生成各种类型的随机数。

# 生成一个3x3的随机数组,元素在[0, 1)之间
rand_arr = np.random.rand(3, 3)
print(rand_arr)

# 生成一个服从标准正态分布的随机数组
normal_arr = np.random.randn(3, 3)
print(normal_arr)

# 生成一个0到10之间的随机整数数组
int_arr = np.random.randint(0, 10, size=(3, 3))
print(int_arr)

输出:

示例输出1:
[[0.5488135  0.71518937 0.60276338]
 [0.54488318 0.4236548  0.64589411]
 [0.43758721 0.891773   0.96366276]]

示例输出2:
[[ 1.76405235  0.40015721  0.97873798]
 [ 2.2408932   1.86755799 -0.97727788]
 [ 0.95008842 -0.15135721 -0.10321885]]

示例输出3:
[[5 0 3]
 [3 7 9]
 [3 5 2]]

这些随机数生成函数在数据科学、机器学习中有着广泛的应用。

5. NumPy与其他Python库的集成

NumPy通常与其他科学计算和数据分析库一起使用,如Pandas、Matplotlib等。它为这些库提供了高效的数组操作支持。

NumPy与Pandas

Pandas是基于NumPy构建的高级数据分析库。Pandas的DataFrameSeries对象在底层都是由NumPy数组支持的。你可以轻松地将NumPy数组转换为Pandas对象,反之亦然。

import pandas as pd

# NumPy数组转Pandas DataFrame
arr = np.array([[1, 2, 3], [4, 5, 6]])
df = pd.DataFrame(arr, columns=['A', 'B', 'C'])
print(df)

# Pandas DataFrame转NumPy数组
arr_from_df = df.values
print(arr_from_df)

输出:

   A  B  C
0  1  2  3
1  4  5  6

[[1 2 3]
 [4 5 6]]
NumPy与Matplotlib

Matplotlib是一个流行的绘图库,通常与NumPy结合使用来可视化数据。通过将NumPy数组传递给Matplotlib的绘图函数,你可以轻松绘制图形。

import matplotlib.pyplot as plt

# 使用NumPy创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 绘制图形
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.show()

这段代码生成了一条从0到10的正弦波曲线。


第五部分:NumPy性能优化与多线程操作

1. NumPy的性能优化

NumPy的强大之处不仅在于它简洁的数组操作,还在于它在处理大规模数据时的高效性。在实际应用中,性能优化往往是我们需要考虑的重要方面。

使用向量化操作代替Python循环

在NumPy中,向量化操作通常比使用Python循环更快。原因在于NumPy的底层实现使用了高度优化的C代码,可以并行处理数据,减少Python解释器的开销。

import numpy as np
import time

# 创建一个大数组
arr = np.arange(1e7)

# 使用Python循环计算平方和
start_time = time.time()
sum_squares_loop = sum(x**2 for x in arr)
end_time = time.time()
print("Python循环时间:", end_time - start_time)

# 使用NumPy向量化计算平方和
start_time = time.time()
sum_squares_np = np.sum(arr ** 2)
end_time = time.time()
print("NumPy向量化时间:", end_time - start_time)

输出:

Python循环时间: 0.8秒
NumPy向量化时间: 0.01秒

可以看到,NumPy的向量化操作在处理大规模数据时,速度显著快于Python的for循环。

内存布局和连续性

NumPy数组在内存中的布局对性能也有很大的影响。NumPy数组可以是行优先(C风格)或列优先(Fortran风格)的,行优先数组在逐行访问时更快,而列优先数组在逐列访问时更快。

arr_c = np.ones((10000, 10000), order='C')
arr_f = np.ones((10000, 10000), order='F')

# 测试行优先数组的访问速度
start_time = time.time()
arr_c_sum = arr_c[::, ::1].sum()
end_time = time.time()
print("行优先访问时间:", end_time - start_time)

# 测试列优先数组的访问速度
start_time = time.time()
arr_f_sum = arr_f[::, ::1].sum()
end_time = time.time()
print("列优先访问时间:", end_time - start_time)

通过控制数组的内存布局,可以在特定的应用场景下进一步优化性能。

2. 多线程与并行计算

NumPy与多线程

虽然Python的全局解释器锁(GIL)限制了多线程的并行计算能力,但NumPy内部的许多操作是使用底层的C代码实现的,能够释放GIL。因此,某些NumPy操作可以在多线程环境中并行执行。

import threading

# 定义一个函数来计算数组的平方和
def compute_square_sum(arr):
    print(np.sum(arr ** 2))

# 创建一个大数组
arr = np.arange(1e6)

# 启动多个线程同时计算
thread1 = threading.Thread(target=compute_square_sum, args=(arr,))
thread2 = threading.Thread(target=compute_square_sum, args=(arr,))

thread1.start()
thread2.start()

thread1.join()
thread2.join()

尽管这在某些情况下可以提升性能,但多线程的实际效果依赖于具体的操作和硬件条件。在大多数情况下,推荐使用多进程或其他并行计算库(如multiprocessingjoblib)来实现真正的并行计算。

使用NumPy进行并行化计算

对于需要在多核CPU上进行并行计算的任务,可以使用numexpr库。它可以将复杂的计算表达式编译为并行代码,以显著提高性能。

import numexpr as ne

arr = np.arange(1e7)

# 使用numexpr进行并行化计算
result = ne.evaluate("arr ** 2 + arr * 2 + 3")
print(result)

numexpr库可以自动识别并利用CPU的多核资源,使得计算任务能够并行执行,从而大幅度提高性能。

3. 大规模数据处理中的实践

使用内存映射文件处理大数据

对于超大数据集,直接加载到内存中可能是不切实际的。NumPy的内存映射(memory-mapped)文件功能允许我们将磁盘上的文件映射为NumPy数组,以便在不加载整个文件到内存的情况下进行处理。

# 创建一个内存映射文件
mmap_arr = np.memmap('large_array.dat', dtype='float32', mode='w+', shape=(10000, 10000))

# 对内存映射数组进行操作
mmap_arr[:] = np.random.rand(10000, 10000)

# 刷新到磁盘
mmap_arr.flush()

# 读取内存映射文件
mmap_arr_read = np.memmap('large_array.dat', dtype='float32', mode='r', shape=(10000, 10000))
print(mmap_arr_read)

内存映射文件特别适合处理大数据集和需要频繁访问的文件,如处理视频数据、天文数据等。

使用NumPy进行批量处理

在数据科学和机器学习中,处理大规模数据时常常需要将数据分批次加载。NumPy可以通过分批处理和生成器来有效管理大数据集的内存使用。

def batch_generator(arr, batch_size):
    total_size = arr.shape[0]
    for i in range(0, total_size, batch_size):
        yield arr[i:i+batch_size]

arr = np.arange(1e6)
batch_size = 100000

for batch in batch_generator(arr, batch_size):
    # 对每个批次进行处理
    print(np.sum(batch))

使用生成器和批处理可以确保程序在处理大数据时不会因内存不足而崩溃,同时也能提高处理效率。

4. NumPy常见问题与最佳实践

避免不必要的数据拷贝

在操作大数据集时,尽量避免不必要的数据拷贝,以减少内存使用和提高效率。NumPy的切片操作通常返回原数组的视图而非副本,因此可以使用切片操作来避免拷贝。

arr = np.arange(1e7)
sub_arr = arr[::2]  # 这是一个视图,不会产生拷贝
sub_arr_copy = arr[::2].copy()  # 显式地创建一个副本
谨慎使用循环

虽然有些情况下需要使用循环,但在处理大规模数组时,尽量使用NumPy的向量化操作而非显式循环。这不仅可以简化代码,还能大大提升性能。

善用NumPy的广播机制

广播机制可以减少显式的重复操作和数据复制。在编写代码时,尽量利用广播机制来简化数组操作,避免不必要的for循环。

定期检查内存使用情况

处理大数据集时,定期检查程序的内存使用情况,及时释放不再需要的内存。使用Python的gc模块可以手动进行垃圾回收,以释放未被及时回收的内存。

import gc
gc.collect()

总结与展望

在本文的前半部分,我们系统地探讨了NumPy的基础与进阶操作,涵盖了从数组的创建与操作到矩阵运算、性能优化、多线程处理等内容。通过这些讲解与示例,你现在应该已经掌握了如何高效地使用NumPy进行科学计算和数据处理。


NumPy不仅在日常的数据分析中表现出色,还为复杂的工程和科学应用提供了坚实的基础。理解并灵活应用NumPy的各种功能,将使你在数据处理和算法实现方面更具优势。


在接下来的部分中,我们将继续深入探索NumPy的高级应用,特别是在科学计算、信号处理、图像处理和机器学习中的实际应用。这些内容将帮助你进一步提升数据处理的效率和质量,为你在更复杂的项目中奠定坚实的基础。

敬请期待!


以上就是关于【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧的内容啦,各位大佬有什么问题欢迎在评论区指正,或者私信我也是可以的啦,您的支持是我创作的最大动力!❤️

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
目录
相关文章
|
9天前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
Pandas 和 NumPy 是 Python 中不可或缺的数据处理和分析工具。本文通过实际案例深入剖析了 Pandas 的数据清洗、NumPy 的数组运算、结合两者进行数据分析和特征工程,以及 Pandas 的时间序列处理功能。这些高级技巧能够帮助我们更高效、准确地处理和分析数据,为决策提供支持。
21 2
|
15天前
|
存储 数据处理 Python
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第27天】在科学计算和数据分析领域,Python凭借简洁的语法和强大的库支持广受欢迎。NumPy和SciPy作为Python科学计算的两大基石,提供了高效的数据处理和分析工具。NumPy的核心功能是N维数组对象(ndarray),支持高效的大型数据集操作;SciPy则在此基础上提供了线性代数、信号处理、优化和统计分析等多种科学计算工具。结合使用NumPy和SciPy,可以显著提升数据处理和分析的效率,使Python成为科学计算和数据分析的首选语言。
25 3
|
15天前
|
机器学习/深度学习 算法 编译器
Python程序到计算图一键转化,详解清华开源深度学习编译器MagPy
【10月更文挑战第26天】MagPy是一款由清华大学研发的开源深度学习编译器,可将Python程序一键转化为计算图,简化模型构建和优化过程。它支持多种深度学习框架,具备自动化、灵活性、优化性能好和易于扩展等特点,适用于模型构建、迁移、部署及教学研究。尽管MagPy具有诸多优势,但在算子支持、优化策略等方面仍面临挑战。
41 3
|
17天前
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
37 5
|
16天前
|
存储 机器学习/深度学习 算法
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第26天】NumPy和SciPy是Python科学计算领域的两大核心库。NumPy提供高效的多维数组对象和丰富的数学函数,而SciPy则在此基础上提供了更多高级的科学计算功能,如数值积分、优化和统计等。两者结合使Python在科学计算中具有极高的效率和广泛的应用。
31 2
|
27天前
|
Python
【10月更文挑战第15天】「Mac上学Python 26」小学奥数篇12 - 图形变换与坐标计算
本篇将通过 Python 和 Cangjie 双语实现图形变换与坐标计算。这个题目帮助学生理解平面几何中的旋转、平移和对称变换,并学会用编程实现坐标变化。
63 1
|
30天前
|
数据可视化 Python
【10月更文挑战第12天】「Mac上学Python 23」小学奥数篇9 - 基础概率计算
本篇将通过 Python 和 Cangjie 双语实现基础概率的计算,帮助学生学习如何解决简单的概率问题,并培养逻辑推理和编程思维。
48 1
|
30天前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--进阶
Python数据分析篇--NumPy--进阶
16 0
|
30天前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--入门
Python数据分析篇--NumPy--入门
32 0
|
3月前
|
Python
Python计算误码率,输入是0-1比特流矩阵和小数矩阵
本文提供了一个Python函数calculate_ber,用于计算两个NumPy矩阵表示的二进制信号和接收信号之间的误码率(BER),其中包括信号与接收信号的比较、误差计数以及BER的计算过程,并给出了具体的使用示例。
66 2