在数据科学领域,NumPy (Numerical Python) 无疑是最核心的库之一。它为我们提供了高效处理大型多维数组的能力,而数组的创建是所有操作的起点。本篇将详细介绍 NumPy 中最常用的几个数组创建函数:np.array()
, np.arange()
, np.zeros()
, np.ones()
, 和 np.linspace()
。理解这些函数能让你游刃有余地构建各种所需的数值数组。
在前面我们已经提到了 Python 列表在处理大量数值数据时的局限性。NumPy 的核心是其 ndarray
对象,它是一个多维的、同质的、高效的数据容器。为了充分利用 ndarray
的优势,我们需要专门的函数来创建它们。这些函数不仅能快速初始化数组,还能在创建时指定数据类型、形状等重要属性,从而满足不同的计算需求。
我们将逐一介绍这些基本且重要的数组创建函数。
np.array()
:从现有数据创建数组np.array()
是最通用、最灵活的数组创建函数。它允许你从 Python 的列表、元组或其他序列类型数据中创建 ndarray
。
ndarray
。object
: 任何暴露数组接口的对象、或任何序列。dtype
: 可选参数,指定数组元素的数据类型。如果未指定,NumPy 会自动推断最合适的数据类型。copy
: 可选参数,布尔值。如果为 True
(默认),则总是复制输入数据;如果为 False
,则仅在输入不是 ndarray
时复制,否则尝试返回视图。示例与说明:
import numpy as np
# 从列表创建一维数组
list1 = [1, 2, 3, 4, 5]
arr1d = np.array(list1)
print("一维数组 (来自列表):", arr1d)
print("类型:", type(arr1d), "Dtype:", arr1d.dtype)
# 从元组创建一维数组
tuple1 = (6, 7, 8)
arr1d_from_tuple = np.array(tuple1)
print("一维数组 (来自元组):", arr1d_from_tuple)
# 从嵌套列表创建二维数组 (矩阵)
list2d = [[10, 11, 12], [13, 14, 15]]
arr2d = np.array(list2d)
print("\n二维数组 (来自嵌套列表):\n", arr2d)
print("形状:", arr2d.shape, "Dtype:", arr2d.dtype)
# 创建时指定数据类型
arr_float = np.array([1, 2, 3], dtype=np.float64) # 强制为 float64
print("\n指定 float64 类型数组:", arr_float)
print("Dtype:", arr_float.dtype)
arr_bool = np.array([0, 1, 0, 100], dtype=np.bool_) # 0 为 False,非 0 为 True
print("指定 bool 类型数组:", arr_bool)
print("Dtype:", arr_bool.dtype)
# 创建三维数组
list3d = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
arr3d = np.array(list3d)
print("\n三维数组:\n", arr3d)
print("形状:", arr3d.shape)
何时使用 np.array()
?
当你已经有现成的 Python 列表、元组或其他可迭代对象,并希望将其转换为 NumPy 数组以便进行高效的数值计算时,np.array()
是首选。
np.arange()
:创建等差序列np.arange()
函数类似于 Python 内置的 range()
函数,但它返回的是一个 ndarray
对象,而不是一个迭代器。
start
: 可选参数,序列的起始值(包含)。默认为 0。stop
: 序列的终止值(不包含)。step
: 可选参数,序列中数值之间的步长。默认为 1。dtype
: 可选参数,指定结果数组的数据类型。示例与说明:
# 从 0 到 10 (不包含 10),步长为 1
arr_range1 = np.arange(10)
print("\narange(10):", arr_range1)
# 从 1 到 10 (不包含 10),步长为 2
arr_range2 = np.arange(1, 10, 2)
print("arange(1, 10, 2):", arr_range2)
# 负数步长,实现倒序
arr_range_rev = np.arange(10, 0, -1)
print("arange(10, 0, -1):", arr_range_rev)
# 浮点数步长
arr_range_float = np.arange(0.0, 5.0, 0.5)
print("arange(0.0, 5.0, 0.5):", arr_range_float)
print("Dtype:", arr_range_float.dtype) # 自动推断为 float64
# 指定 dtype
arr_range_int8 = np.arange(5, dtype=np.int8)
print("arange(5, dtype=np.int8):", arr_range_int8)
print("Dtype:", arr_range_int8.dtype)
何时使用 np.arange()
?
当你需要创建一个具有固定步长、数值呈等差数列分布的数组时,np.arange()
是理想选择。常用于生成索引、时间序列或简单的数值范围。
np.zeros()
:创建全零数组np.zeros()
函数用于创建一个指定形状的全零数组。
ndarray
。shape
: 整数或整数元组,定义数组的形状(维度)。dtype
: 可选参数,指定数组元素的数据类型。默认为 float64
。示例与说明:
# 创建一个 3 个元素的一维全零数组
zeros_1d = np.zeros(3)
print("\nzeros(3):\n", zeros_1d)
print("Dtype:", zeros_1d.dtype) # 默认 float64
# 创建一个 2x3 的二维全零数组
zeros_2d = np.zeros((2, 3))
print("\nzeros((2, 3)):\n", zeros_2d)
# 创建一个 2x2x2 的三维全零数组,指定为整数类型
zeros_3d_int = np.zeros((2, 2, 2), dtype=int)
print("\nzeros((2, 2, 2), dtype=int):\n", zeros_3d_int)
print("Dtype:", zeros_3d_int.dtype)
# 创建一个 5x1 的全零列向量
zeros_col_vector = np.zeros((5, 1))
print("\nzeros((5, 1)) (列向量):\n", zeros_col_vector)
何时使用 np.zeros()
?
当你需要一个预填充零的数组作为占位符、初始化缓冲区、或者在某些算法中作为计数器时,np.zeros()
非常有用。
np.ones()
:创建全一数组np.ones()
函数类似于 np.zeros()
,但它创建的是一个全一的数组。
ndarray
。shape
: 整数或整数元组,定义数组的形状。dtype
: 可选参数,指定数组元素的数据类型。默认为 float64
。示例与说明:
# 创建一个 4 个元素的一维全一数组
ones_1d = np.ones(4)
print("\nones(4):\n", ones_1d)
# 创建一个 3x2 的二维全一数组,指定为布尔类型
ones_2d_bool = np.ones((3, 2), dtype=bool)
print("\nones((3, 2), dtype=bool):\n", ones_2d_bool) # 1 会被转换为 True
# 创建一个 2x2x1 的三维全一数组
ones_3d = np.ones((2, 2, 1))
print("\nones((2, 2, 1)):\n", ones_3d)
何时使用 np.ones()
?
当需要一个预填充一的数组进行乘法初始化、权重计算或作为某些算法的基准值时,np.ones()
是非常方便的。
np.linspace()
:创建等间隔序列np.linspace()
函数与 np.arange()
类似,都是创建等差序列,但它们在参数定义上有所不同:linspace
侧重于指定起始点、终止点和元素个数,而 arange
侧重于起始点、终止点和步长。
start
: 序列的起始值。stop
: 序列的终止值(默认包含)。num
: 可选参数,要生成的样本数量。默认为 50。endpoint
: 可选参数,布尔值。如果为 True
(默认),则包含 stop
值;如果为 False
,则不包含 stop
值。retstep
: 可选参数,布尔值。如果为 True
,则返回步长。dtype
: 可选参数,结果数组的数据类型。示例与说明:
# 在 0 到 10 之间生成 5 个均匀分布的数 (包含 0 和 10)
arr_linspace1 = np.linspace(0, 10, 5)
print("\nlinspace(0, 10, 5):", arr_linspace1) # [ 0. 2.5 5. 7.5 10. ]
# 在 0 到 10 之间生成 5 个数,但不包含 10
arr_linspace2 = np.linspace(0, 10, 5, endpoint=False)
print("linspace(0, 10, 5, endpoint=False):", arr_linspace2) # [0. 2. 4. 6. 8.]
# 返回步长信息
arr_linspace3, step_size = np.linspace(0, 1, 11, retstep=True)
print("linspace(0, 1, 11, retstep=True):", arr_linspace3)
print("步长:", step_size) # 0.1
# 默认生成 50 个点
arr_linspace_default = np.linspace(0, 1)
print("\nlinspace(0, 1) (默认 50 个点):", arr_linspace_default.shape)
何时使用 np.linspace()
?
当你需要在指定范围内(通常是连续的浮点数范围)生成固定数量的均匀分布点时,np.linspace()
是最佳选择。这在绘制函数图像、模拟连续变量或在给定区间内采样时非常有用。
除了上述五个核心函数,NumPy 还提供了许多其他方便的数组创建函数:
np.empty(shape, dtype)
: 创建指定形状和数据类型的新数组,但不初始化其元素。元素值是随机的(取决于内存中已有的数据)。比 zeros
或 ones
稍快,因为不需填充。np.full(shape, fill_value, dtype)
: 创建指定形状并用 fill_value
填充的数组。np.eye(N, M=None, k=0, dtype=float)
: 创建一个对角线为 1,其他地方为 0 的二维数组(单位矩阵或其变体)。np.identity(N, dtype=None)
: 创建一个 N x N 的单位矩阵。np.copy(a)
: 创建数组 a
的一个副本。np.frombuffer()
, np.fromfile()
, np.fromfunction()
, np.fromiter()
: 从其他源创建数组。本篇详细介绍了 NumPy 中最常用的五种数组创建方法:
np.array()
: 将现有的 Python 序列转换为 ndarray
。np.arange()
: 创建等差序列,通过 start
, stop
, step
控制。np.zeros()
: 创建全零数组,适用于初始化。np.ones()
: 创建全一数组,适用于初始化或作为乘法的基数。np.linspace()
: 创建等间隔序列,通过 start
, stop
, num
控制,特别适合生成连续数据点。熟练掌握这些函数是高效使用 NumPy 的基础,也是迈向更高级数据科学技能的第一步。
尝试独立完成以下练习题,并通过答案进行对照:
使用 np.array()
:
10, 20, 30, 40, 50
的一维 NumPy 数组,并打印其 dtype
。[1.1, 2.2, 3.3]
的一维 NumPy 数组,并打印其 dtype
。[[1, 2, 3], [4, 5, 6]]
。[[True, False], [True, True], [False, False]]
。使用 np.arange()
:
使用 np.zeros()
和 np.ones()
:
int
。bool
。使用 np.linspace()
:
综合应用:
import numpy as np
import math # 用于练习5中的数学常数
print("--- 练习题答案 ---")
# 1. 使用 np.array():
print("\n--- 练习 1: 使用 np.array() ---")
arr_int = np.array([10, 20, 30, 40, 50])
print("整数数组:", arr_int, "Dtype:", arr_int.dtype)
arr_float_explicit = np.array([1.1, 2.2, 3.3])
print("浮点数数组:", arr_float_explicit, "Dtype:", arr_float_explicit.dtype)
arr_2x3 = np.array([[1, 2, 3], [4, 5, 6]])
print("2x3 二维数组:\n", arr_2x3)
arr_bool_2d = np.array([[True, False], [True, True], [False, False]])
print("3x2 布尔数组:\n", arr_bool_2d)
# 2. 使用 np.arange():
print("\n--- 练习 2: 使用 np.arange() ---")
arr_0_to_10 = np.arange(10)
print("0到10 (不含10):", arr_0_to_10)
arr_5_to_15_step3 = np.arange(5, 15, 3)
print("5到15 (不含15), 步长3:", arr_5_to_15_step3)
arr_100_down_to_90 = np.arange(100, 89, -2) # stop 是不包含的,所以是 89
print("100递减到90, 步长-2:", arr_100_down_to_90)
arr_float_step = np.arange(0.1, 1.0, 0.2)
print("0.1到1.0 (不含1.0), 步长0.2:", arr_float_step)
# 3. 使用 np.zeros() 和 np.ones():
print("\n--- 练习 3: 使用 np.zeros() 和 np.ones() ---")
zeros_int = np.zeros(4, dtype=int)
print("4个元素的零向量 (int):", zeros_int)
zeros_3x3 = np.zeros((3, 3))
print("3x3 零矩阵:\n", zeros_3x3)
ones_2x4 = np.ones((2, 4))
print("2x4 一矩阵:\n", ones_2x4)
ones_bool = np.ones(5, dtype=bool)
print("5个元素的一向量 (bool):", ones_bool)
zeros_3x2x2 = np.zeros((3, 2, 2))
print("3x2x2 三维全零数组:\n", zeros_3x2x2)
# 4. 使用 np.linspace():
print("\n--- 练习 4: 使用 np.linspace() ---")
linspace_0_10_5 = np.linspace(0, 10, 5)
print("0到10之间5个点 (包含两端):", linspace_0_10_5)
linspace_neg5_pos5_10_no_endpoint = np.linspace(-5, 5, 10, endpoint=False)
print("-5到5之间10个点 (不含右端):", linspace_neg5_pos5_10_no_endpoint)
linspace_0_2pi_100 = np.linspace(0, 2 * math.pi, 100)
print("0到2pi之间100个点,用于绘图:", linspace_0_2pi_100.shape)
# print(linspace_0_2pi_100) # 打印所有点会太长,只打印形状
# 5. 综合应用:
print("\n--- 练习 5: 综合应用 ---")
identity_matrix = np.eye(3) # 或 np.identity(3)
print("3x3 单位矩阵:\n", identity_matrix)
full_array = np.full((2, 3), 7)
print("2x3 全7数组:\n", full_array)
random_4x4 = np.random.randint(1, 51, size=(4, 4))
print("4x4 随机整数数组 (1-50):\n", random_4x4)
reshaped_array = random_4x4.reshape((2, 8))
print("重塑为 2x8 数组:\n", reshaped_array)