`zeros()`, `ones()`, `empty()`:创建全零、全一、空数组

编程魔法师的百宝箱:zeros(), ones(), empty(),创造数组的初始混沌!

各位编程界的魔法师、炼金术士、以及代码界的段子手们,大家好!我是你们的老朋友,一个沉迷于代码海洋无法自拔的探险家。今天,我们要一起探索一个神奇的宝藏—— NumPy 数组初始化的三大法宝:zeros(), ones(), 和 empty()

想象一下,你是一位伟大的建筑师,准备建造一座壮丽的数字帝国。在开始堆砌砖瓦(数据)之前,你需要一片平坦的土地,或者至少是一些预制板,方便你快速搭建。 这三位法宝,就如同你手中的魔法工具,帮你瞬间创造出各种规格的“地基”,让你的数据城堡从一开始就拥有无限可能。

第一章:zeros() – 零的哲学:一切皆空,一切皆有可能!

zeros() 函数,顾名思义,它的使命就是创造一个充满 “0” 的数组。 就像宇宙大爆炸之前,一片虚无,孕育着无限的可能性。 零,代表着起点,代表着纯粹,也代表着无限的潜力。

语法解析:

import numpy as np

np.zeros(shape, dtype=float, order='C', *, like=None)
  • shape: 这是最重要的参数,决定了你想要创造的数组的形状。 它可以是一个整数 (代表一维数组的长度),也可以是一个元组 (代表多维数组的各个维度的大小)。 例如,shape=5 会创建一个长度为5的一维数组,shape=(2, 3) 会创建一个2行3列的二维数组。
  • dtype: 指定数组中元素的数据类型。 默认情况下是 float64 (双精度浮点数),但你可以根据需求选择其他类型,例如 int32 (32位整数), bool (布尔值), complex128 (128位复数) 等等。 选择合适的数据类型,可以节省内存,提高计算效率。
  • order: 指定数组在内存中的存储顺序。 'C' 代表 C-style (行优先), 'F' 代表 Fortran-style (列优先)。 通常情况下,我们使用默认的 'C' 即可。
  • like: 允许你创建一个与现有数组具有相同属性(形状、数据类型等)的新数组。这是一个非常方便的参数,可以避免重复设置属性。

实战演练:

  1. 一维零数组:

    arr1 = np.zeros(5)
    print(arr1)  # 输出: [0. 0. 0. 0. 0.]

    这里,我们创造了一个包含5个元素的,类型为浮点数的零数组。 就像五个空荡荡的房间,等待着你的数据入住。

  2. 二维零数组:

    arr2 = np.zeros((3, 4))
    print(arr2)
    # 输出:
    # [[0. 0. 0. 0.]
    #  [0. 0. 0. 0.]
    #  [0. 0. 0. 0.]]

    这是一个3行4列的矩阵,每个元素都是0。 想象一下,这是一个电子表格,你还没有填入任何数据,等待着你来创造价值。

  3. 指定数据类型:

    arr3 = np.zeros((2, 2), dtype=int)
    print(arr3)
    # 输出:
    # [[0 0]
    #  [0 0]]

    现在,我们创造了一个2×2的整数零数组。 就像一个棋盘,等待着黑白棋子的入场。

  4. 使用 like 参数:

    existing_arr = np.array([[1, 2, 3], [4, 5, 6]])
    new_arr = np.zeros_like(existing_arr)
    print(new_arr)
    # 输出:
    # [[0 0 0]
    #  [0 0 0]]

    new_arr 继承了 existing_arr 的形状和数据类型 (在这种情况下是整数),并用 0 填充。 这就像克隆一个数组的骨架,然后用零填充它的血肉。

应用场景:

  • 初始化计数器: 在统计分析中,我们经常需要初始化一个计数器数组,用于记录各种事件发生的次数。 zeros() 可以方便地创建这样一个数组,所有计数器初始值为0。
  • 作为占位符: 在进行复杂计算时,我们可能需要先创建一个空数组,然后逐步填充数据。 zeros() 可以作为占位符,预先分配内存空间,避免动态分配带来的性能损耗。
  • 图像处理: 在图像处理中,我们可以使用 zeros() 创建一个空白图像,然后在其上绘制图形或进行其他操作。

总结:

zeros() 就像一位谦逊的艺术家,用零作为画布,为你提供无限的创作空间。 无论是初始化数据结构,还是预分配内存,它都是你的得力助手。

第二章:ones() – 一的坚持:万物归一,力量的源泉!

如果说 zeros() 代表着虚无和起点,那么 ones() 则代表着团结、力量和坚持。 ones() 函数用于创建一个充满 “1” 的数组。 “1” 代表着基本单位,代表着存在,也代表着一种积极向上的力量。

语法解析:

ones() 的语法与 zeros() 非常相似:

import numpy as np

np.ones(shape, dtype=float, order='C', *, like=None)

参数的含义与 zeros() 完全相同,只是这次填充的是 “1” 而不是 “0”。

实战演练:

  1. 一维全一数组:

    arr1 = np.ones(3)
    print(arr1)  # 输出: [1. 1. 1.]

    三个 “1” 并排站立,代表着团结一致,力量无穷。

  2. 二维全一数组:

    arr2 = np.ones((2, 5), dtype=int)
    print(arr2)
    # 输出:
    # [[1 1 1 1 1]
    #  [1 1 1 1 1]]

    一个2行5列的全一矩阵,象征着团队协作,共同努力。

  3. 使用 like 参数:

    existing_arr = np.array([[1.0, 2.0], [3.0, 4.0]]) # 注意这里是浮点数
    new_arr = np.ones_like(existing_arr)
    print(new_arr)
    # 输出:
    # [[1. 1.]
    #  [1. 1.]]

    克隆 existing_arr 的形状和数据类型,并用 “1” 填充。 注意,这里 new_arr 的数据类型也是浮点数,因为 existing_arr 是浮点数类型的。

应用场景:

  • 图像处理: 创建白色图像 (在灰度图像中,255 通常代表白色,而全是 “1” 的浮点数数组可以近似表示白色)。
  • 掩码操作: 在图像处理或数据分析中,可以使用全一数组作为掩码,用于选择或过滤特定的数据。
  • 缩放操作: 将数组乘以一个全一数组,可以实现缩放操作。
  • 作为基准值: 在某些算法中,需要一个全一数组作为基准值,用于进行比较或计算。

总结:

ones() 函数如同一个坚定的战士,用 “1” 铸造你的数据城堡,为你提供稳定的基石和强大的力量。

第三章:empty() – 空的艺术:混沌之初,无限可能!

empty() 函数是三者中最神秘,也最具有哲学意味的一个。 它并不像 zeros()ones() 那样,用特定的值填充数组,而是仅仅分配内存空间,留下数组中的元素为“垃圾值”。 这就像宇宙大爆炸的瞬间,能量爆发,混沌一片,充满了未知和可能性。

语法解析:

import numpy as np

np.empty(shape, dtype=float, order='C', *, like=None)

参数的含义与 zeros()ones() 相同。

实战演练:

import numpy as np

arr1 = np.empty((2, 3))
print(arr1)
# 输出 (结果可能不同,取决于内存中的垃圾值):
# [[6.90948847e-310 6.90948847e-310 6.90948847e-310]
#  [6.90948847e-310 6.90948847e-310 6.90948847e-310]]

arr2 = np.empty((2, 2), dtype=int)
print(arr2)
# 输出 (结果可能不同,取决于内存中的垃圾值):
# [[6422256 6422528]
#  [  16912 13451376]]

可以看到,empty() 创建的数组中,元素的值是随机的,取决于内存中之前存储的数据 (也就是所谓的“垃圾值”)。 每次运行,结果都可能不同。

注意事项:

  • 不要假设 empty() 创建的数组中的值为 0! 虽然有时结果看起来像 0,但这仅仅是巧合。 依赖于这些“垃圾值”是极其危险的,会导致程序出现不可预测的错误。
  • 在使用 empty() 创建的数组之前,务必对其进行初始化! 例如,可以使用循环或向量化操作,将数组中的元素设置为你想要的值。

应用场景:

  • 性能优化: 在需要频繁创建和销毁数组的场景下,使用 empty() 可以避免不必要的初始化操作,从而提高性能。 但是,必须确保在使用之前,对数组进行正确的初始化。
  • 作为缓冲区: 在某些情况下,可以使用 empty() 创建一个缓冲区,用于存储中间计算结果。 这可以避免频繁的内存分配和释放操作。

总结:

empty() 函数就像一个充满未知力量的黑洞,它为你提供一块原始的画布,但需要你亲自去填充色彩。 它高效而危险,只有经验丰富的魔法师才能驾驭。

第四章:三剑客的巅峰对决:选择哪一个?

现在,我们已经了解了 zeros(), ones(), 和 empty() 这三位 NumPy 数组初始化的法宝。 那么,在实际应用中,我们应该选择哪一个呢?

功能/特性 zeros() ones() empty()
初始值 全零 全一 垃圾值 (未初始化)
适用场景 需要初始化为零的数组,例如计数器、占位符 需要初始化为一的数组,例如掩码、基准值 对初始值没有要求,追求性能的场景
性能 相对较慢 (需要初始化) 相对较慢 (需要初始化) 最快 (无需初始化)
安全性 高 (初始值为零,易于调试) 高 (初始值为一,易于调试) 低 (需要在使用前进行初始化,容易出错)
使用难度 中 (需要理解未初始化的概念,避免错误使用)

选择建议:

  • 如果你需要一个初始值为 0 的数组,那么毫不犹豫地选择 zeros() 它是最安全,也是最常用的选择。
  • 如果你需要一个初始值为 1 的数组,那么 ones() 是你的最佳选择。
  • 如果你对性能有极致的追求,并且确信自己能够在使用前正确地初始化数组,那么可以考虑使用 empty() 但是,请务必小心,避免出现未初始化变量的错误。

总而言之,在选择时,你需要权衡性能、安全性和易用性,选择最适合你当前需求的法宝。

第五章:更高级的魔法:full()full_like()

除了 zeros(), ones(), 和 empty() 之外,NumPy 还提供了 full()full_like() 函数,用于创建填充特定值的数组。

full() 函数:

full() 函数可以创建一个填充任意值的数组。

import numpy as np

np.full(shape, fill_value, dtype=None, order='C', *, like=None)
  • shape: 数组的形状。
  • fill_value: 用于填充数组的值。
  • dtype: 数组的数据类型。

full_like() 函数:

full_like() 函数可以创建一个与现有数组具有相同属性,并填充特定值的数组。

import numpy as np

np.full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None)
  • a: 作为模板的数组。
  • fill_value: 用于填充数组的值。
  • dtype: 数组的数据类型。

示例:

import numpy as np

# 创建一个 2x3 的数组,所有元素都为 7
arr1 = np.full((2, 3), 7)
print(arr1)
# 输出:
# [[7 7 7]
#  [7 7 7]]

# 创建一个与 existing_arr 具有相同属性,并填充值为 -1 的数组
existing_arr = np.array([[1, 2], [3, 4]])
arr2 = np.full_like(existing_arr, -1)
print(arr2)
# 输出:
# [[-1 -1]
#  [-1 -1]]

full()full_like() 提供了更灵活的数组初始化方式,可以满足各种特殊需求。

尾声:数组的无限可能

好了,各位魔法师们,今天的 NumPy 数组初始化之旅就到这里。 我们一起探索了 zeros(), ones(), empty(), full()full_like() 这五位强大的法宝。 希望它们能成为你代码百宝箱中的得力助手,帮助你创造出更加精彩的数字世界。

记住,代码的世界是无限的,学习永无止境。 让我们一起保持好奇心,不断探索,共同进步! 下次再见! 😉

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注