今天学习了numpy,又新总结了许多心得体会,在数据科学与计算的领域中,NumPy 作为一款开源的 Python 科学计算库,其重要性不言而喻。通过对 NumPy 相关知识的学习,我不仅掌握了数组操作的核心技能,更深刻体会到它在简化代码、提升计算效率方面的强大能力,为后续更复杂的数据分析和科学计算打下了坚实基础。NumPy 的学习始于其安装与导入,看似简单的步骤却是使用它的前提。安装时可以选择pip install numpy或者conda install numpy命令,为了提高下载速度,还能借助清华源,这让我明白在工具使用初期,选择合适的资源获取方式能节省不少时间。而导入时约定俗成的import numpy as np,则体现了编程领域的简洁与规范,方便了开发者之间的交流与协作。NumPy 的核心是Ndarray 对象,即 N 维数组。它是一系列同类型数据的集合,以 0 下标为开始进行元素索引。这种同类型数据的特性,使得 NumPy 在存储和计算时更加高效,与 Python 中的列表相比,避免了不同数据类型带来的额外开销。理解 Ndarray 对象是掌握 NumPy 的关键,它就像一个容器,承载着后续所有操作的数据。而数据创建需要多样函数满足不同需求。
创建 Ndarray 数组的函数丰富多样,每种函数都有其独特的应用场景,熟练掌握它们能让我们在不同情境下快速构建所需数组。
array()函数是最基础也是最常用的,它可以将数组或嵌套的数列转换为 Ndarray 数组,还能通过dtype参数指定数据类型,ndmin参数指定最小维度等,灵活性极高。比如从一个简单的列表[1,2,3],我们可以轻松创建出一维数组,也能通过嵌套列表创建多维数组。
empty()函数用于创建一个指定形状和数据类型但未初始化的数组,它不会为数组元素赋予初始值,因此创建速度较快,但数组中的值是随机的,适合在我们明确后续会为数组赋值,且希望快速开辟内存空间的场景。zeros()和ones()函数则分别创建元素全为 0 和全为 1 的数组,在初始化一些需要基准值的数组时非常有用。例如在进行矩阵运算时,初始化为全 0 数组作为结果容器,再逐步填充计算结果。而数组属性需要了解数组的身份信息。Ndarray 数组的属性为我们提供了数组的基本信息,帮助我们更好地理解和操作数组。ndim属性表示数组的秩,即维度数量,通过它我们可以快速判断数组是一维、二维还是更高维。例如一个二维数组的ndim值为 2。shape属性描述了数组的维度,对于矩阵来说,就是行数和列数,如(2,3)表示一个 2 行 3 列的数组。我们还可以通过修改shape的值来改变数组的维度,实现数组的重塑,而无需改变数组元素。size属性给出了数组元素的总个数,等于shape中各维度数值的乘积,让我们能快速了解数组的数据量大小。dtype属性则显示了数组元素的数据类型,NumPy 支持多种数据类型,如int32、float64等,明确数据类型有助于我们在计算时避免类型错误,同时也能根据需求选择合适的类型以节省内存。
数据和索引需要灵活访问数组元素。
与 Python 中的列表类似,Ndarray 数组可以通过索引和切片来访问和修改元素,这为我们操作数组中的特定元素或子数组提供了极大便利。
索引可以获取数组中的单个元素,对于多维数组,我们可以通过多个索引值来定位元素,如arr[2][1]可以获取二维数组中第 3 行第 2 列的元素。
切片则可以从数组中切割出一个新的子数组,通过start:stop:step的形式来指定切片范围。对于多维数组,还可以对不同维度分别进行切片。此外,省略号 “...” 在切片中非常实用,它可以使选择元组的长度与数组的维度相同,简化了高维数组的切片操作。
而今天的练习除了要复现老师给我们布置的代码外,另有老师布置的任务要做,复现的代码有二十多个,再此不做一一赘述,仅以几个为例。
# 一维数组
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
# 元素类型要相同
arr = np.array([1, 2, 3, 4.5, 5, 6, 7, 8])
print(arr)
print(type(arr))
# 多维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(type(arr))
#创建一个二维数组
arr = np.empty([3, 2], dtype=int)
print(arr)
print(type(arr))
#随机生成二维
arr = np.empty([3, 2], dtype=int)
print(arr)
# 创建一个长度为5的浮点数数组,所有元素初始化为0.0
arr = np.zeros(5)
print(arr)
# 创建一个长度为5的整数数组,所有元素初始化为0
arr = np.zeros(5, dtype=int)
print(arr)
# 创建一个3行2列的数组,所有元素初始化为1,数据类型为int32
arr = np.ones([3, 2], dtype='i4')
print(arr)
# 创建一个3行2列的数组,所有元素初始化为1024,数据类型为int32
arr = np.full([3, 2], fill_value=1024, dtype='i4')
print(arr)
# 创建一个10x10的单位矩阵(Identity Matrix),数据类型为int32
arr = np.eye(10, dtype='i4')
print(arr)
# 创建一个包含从1到10的数组,步长为1
arr = np.arange(1, 11, 1)
print(arr)
# 创建一个包含从1到11(不包括11)的数组,步长为2
arr = np.arange(1, 11, 2)
print(arr)
# 输出一个数组,其中每个元素是原始字节字符串中的一个字节
s = b"sunck is a good man"
arr = np.frombuffer(s, dtype='S1')
print(arr)
# 输出一个数组,包含字节字符串s的前5个字节
s = b"sunck is a good man"
arr = np.frombuffer(s, dtype='S1', count=5)
print(arr)
# 输出一个数组,包含从字节字符串s的第3个字节开始的5个字节
s = b"sunck is a good man"
arr = np.frombuffer(s, dtype='S1', count=5, offset=2)
print(arr)
# 创建一个包含从1到10的数组,共有10个元素,数据类型为int32
arr = np.linspace(1, 10, 10, dtype='i4')
print(arr)
# 创建一个包含从1到2的对数等差数列的数组,共有10个元素,数据类型为int32
arr = np.logspace(1, 2, 10, dtype='i4')
print(arr)
# 生成一个随机的浮点数
arr = np.random.rand()
# 打印生成的随机数及其类型
print(arr, type(arr))
# 生成一个包含5个随机浮点数的一维数组
arr = np.random.rand(5)
print(arr)
# 生成一个3x2的二维数组,包含随机浮点数
arr = np.random.rand(3, 2)
print(arr)
# 再次生成一个3x2x2的三维数组,包含随机浮点数
arr = np.random.rand(3, 2, 2)
print(arr)
# 生成一个包含三个随机数的数组
arr = np.random.random(3)
print(arr)
# 生成一个包含5个随机整数的数组,这些整数的范围是从0到9(包括0,不包括10)
arr = np.random.randint(0, 10, 5)
print(arr)
# 生成了一个2行4列的数组,其中的元素是从标准正态分布(均值为0,方差为1)中抽取的随机样本
arr = np.random.randn(2, 4)
print(arr)
# 生成了一个4行3列2层的数组,同样元素也是从标准正态分布中抽取的随机样本
arr = np.random.randn(4, 3, 2)
print(arr)
# 生成一个包含5个随机数的数组。这些随机数服从均值为1、标准差为2的正态分布
arr = np.random.normal(loc=1, scale=2, size=5)
print(arr)
# 生成了一个包含1000万个随机数的列表,并测量了计算这些数总和所需的时间1
import random
li = []
for i in range(10000000):
li.append(random.random())
import time
t1 = time.time()
ret1 = sum(li)
t2 = time.time()
print("耗时: %f" % (t2-t1))
print(ret1)
# 生成了一个包含1000万个随机数的列表,并测量了计算这些数总和所需的时间2
import numpy as np
import time
n = np.array(li)
t1 = time.time()
ret2 = np.sum(n)
t2 = time.time()
print("耗时: %f" % (t2 - t1))
print(ret2)
# 这段代码演示了如何使用NumPy创建一维数组、查看其维度、并将其重塑为三维数组
import numpy as np
arr = np.arange(24)
print(arr)
print(arr.ndim)
arr2 = arr.reshape(2, 3, 4)
print(arr2)
print(arr2.ndim)
# 创建一个二维数组查看
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(arr.shape)
# 修改数组的形状
arr = np.array([[1, 2, 3], [4, 5, 6]])
arr.shape = (3, 2)
print(arr)
print(arr.shape)
# 创建了一个2x3的二维NumPy数组,并打印了数组的内容、元素总数(size)以及数组的数据类型
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(arr.size)
print(arr.dtype)
# 创建了一个包含0到9的一维NumPy数组,并打印了整个数组及其索引为1的元素(值为1)
arr = np.arange(10)
print(arr)
print(arr[1])
# 这段代码使用Python的slice函数创建了一个切片对象s,用于从数组arr中提取从索引2开始到索引7(不包括7)的元素,步长为2,即提取索引为2、4、6的元素。然后,它打印出这些被选中的元素,结果为array([2, 4, 6])
arr = np.arange(10) # 假设这是之前创建的数组
s = slice(2, 7, 2)
print(arr[s])
# 创建了一个包含0到14的一维NumPy数组arr,然后将其形状修改为5行3列的二维数组,打印出整个数组arr和数组的第三行
arr = np.arange(15)
arr.shape = (5, 3)
print(arr)
arr2 = arr[2]
print(arr2)
# 创建了一个包含0到14的一维NumPy数组arr,然后将其形状修改为5行3列的二维数组。接着印出整个数组arr,然后提取第三行第二列的元素(值为7),并打印出该元素及其数据类型
arr = np.arange(15)
arr.shape = (5, 3)
print(arr)
arr2 = arr[2][1]
print(arr2, type(arr2))
# 创建了一个包含0到14的一维NumPy数组arr,然后将其形状修改为5行3列的二维数组。接着印出整个数组arr,然后提取从第三行开始的所有行(即索引为2及之后的行),并打印出这部分数组arr2及其数据类型
arr = np.arange(15)
arr.shape = (5, 3)
print(arr)
print("\n")
arr2 = arr[2:]
print(arr2, type(arr2))
# 使用NumPy创建一个5x3的二维数组,并展示了如何通过不同的索引方式来访问和打印数组的特定行、列或元素。
arr = np.arange(15)
arr.shape = (5, 3)
print(arr)
print("\n")
print(arr[..., 1])
print("\n")
print(arr[1, ...])
print("\n")
print(arr[1:3, ...])
print("\n")
print(arr[..., 1:])
import numpy as np
# 1. 生成一个3*3的对角矩阵
A = np.diag([1, 2, 3])
print("3*3对角矩阵:")
print(A)
# 2. 创建一个长度为10的数组,值为0~1之间,不包含首尾
B = np.linspace(0.1, 0.9, 10)
print("\n0~1之间的数组(不包含首尾):")
print(B)
# 3. 创建一个长度为10的0数组,第5个值为1
C = np.zeros(10)
C[4] = 1 # 第5个元素的索引是4
print("\n长度为10的0数组,第5个值为1:")
print(C)
# 4. 创建一个值从30到50,步长为2的数组
D = np.arange(30, 52, 2)
print("\n值从30到50,步长为2的数组:")
print(D)
# 5. 创建一个四边为1,中间为0的二维数组
E = np.ones((5, 5))
E[1:-1, 1:-1] = 0
print("\n四边为1,中间为0的二维数组:")
print(E)
# 创建一个2*3的二维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 输出数组
print("数组:")
print(arr)
# 输出数组的维度
print("\n维度(行数,列数):", arr.shape)
# 输出数组的行数
print("行数:", arr.shape[0])
# 输出数组的列数
print("列数:", arr.shape[1])
# 输出数组的元素个数
print("元素个数:", arr.size)
# 计算每个维度的大小
depth = 6 # 矩阵有6层
height = 7 # 每层有7行
width = 8 # 每行有8个元素
# 计算索引
index = 99 # 第100个元素的索引
# 计算在每个维度上的位置
d = index // (height * width) # 将元素的总索引除以高度和宽度的乘积得到的
h = (index % (height * width)) // width # 先计算元素索引对高度和宽度乘积的余数,然后除以宽度得到
w = (index % (height * width)) % width # 先计算余数,然后对宽度取余数得到
print(f"第100个元素的索引是: ({d}, {h}, {w})")
# 创建一个示例二维数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 打印初始数组
print("初始数组:")
print(arr)
# 交换第1列和第2列(索引为1和0)
arr[:, [1, 0]] = arr[:, [0, 1]]
# 打印交换后的数组
print("\n交换后的数组:")
print(arr)
而我在学习 NumPy 的过程中,也遇到了一些挑战。比如在理解不同数组创建函数的细微差别时,需要反复对比它们的参数和作用,才能准确把握其适用场景。在处理多维数组的切片和索引时,初期容易混淆各维度的顺序,通过大量练习才逐渐熟练。但每一次克服困难都带来了新的收获。通过对比 NumPy 数组与 Python 列表,我深刻感受到 NumPy 在处理大量数据时的高效性,尤其是在进行数值计算时,NumPy 的向量化操作避免了循环语句,大大提升了计算速度和代码的简洁性。课堂练习也起到了很好的巩固作用,比如生成特定结构的数组、获取数组的各种属性等,让我在实践中加深了对知识点的理解。
9701

被折叠的 条评论
为什么被折叠?



