NumPy Arange:如何创建等间距值的数组
Updated on
创建等间距数字的数组是科学计算、数据分析和机器学习中最常见的操作之一。无论你需要循环的索引序列、绘图的X轴值,还是模拟的网格坐标,你都需要一种快速且可靠的方法来生成它们。Python的内置 range() 函数适用于整数,但当你需要浮点数步长或需要将结果作为NumPy数组进行向量化运算时,它就力不从心了。
这正是 numpy.arange() 所解决的问题。它通过单次函数调用生成等间距值的数组,可以完全控制起始点、终止点、步长和数据类型。本指南涵盖了每个参数,提供了实际示例,将 np.arange() 与 range() 和 np.linspace() 等替代方案进行比较,并向你展示如何避免最常见的错误。
np.arange() 的功能
np.arange() 返回一个一维NumPy数组,包含给定区间内等间距的值。它是Python range() 的NumPy等价物,但返回的是 ndarray 而不是range对象,并且支持浮点数。
以下是完整的函数签名:
numpy.arange([start, ] stop, [step, ] dtype=None)参数参考
| 参数 | 描述 | 默认值 |
|---|---|---|
start | 区间的起始(包含) | 0 |
stop | 区间的结束(不包含) | 必需 |
step | 连续值之间的间距 | 1 |
dtype | 输出数组的数据类型(如 int、float、np.float32) | 从输入推断 |
该函数从 start 开始生成值,每次递增 step,在到达 stop 之前停止。这种"排除stop"的行为与Python的 range() 一致。
基本用法:仅指定Stop值
使用 np.arange() 最简单的方式是传入一个参数。当你传入一个值时,它被视为 stop,start 默认为 0,step 默认为 1。
import numpy as np
arr = np.arange(5)
print(arr)
# Output: [0 1 2 3 4]
print(type(arr))
# Output: <class 'numpy.ndarray'>这创建了一个从0到5(不包含5)的整数数组。注意结果是NumPy的 ndarray,而不是Python列表。这意味着你可以立即在向量化运算中使用它:
import numpy as np
arr = np.arange(5)
print(arr * 10)
# Output: [ 0 10 20 30 40]
print(arr ** 2)
# Output: [ 0 1 4 9 16]使用Start和Stop
传入两个参数来控制序列的起始和结束位置:
import numpy as np
arr = np.arange(2, 10)
print(arr)
# Output: [2 3 4 5 6 7 8 9]数组从 2(包含)开始,在 10(不包含)之前停止。默认步长仍然是 1。
你也可以使用负数起始值:
import numpy as np
arr = np.arange(-3, 4)
print(arr)
# Output: [-3 -2 -1 0 1 2 3]使用Start、Stop和Step
第三个参数控制值之间的间距。这是 np.arange() 比 range() 强大得多的地方,因为步长可以是浮点数:
import numpy as np
arr = np.arange(0, 1, 0.1)
print(arr)
# Output: [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]整数步长的工作方式相同:
import numpy as np
arr = np.arange(0, 20, 3)
print(arr)
# Output: [ 0 3 6 9 12 15 18]步长可以是任何正数。序列总是在到达 stop 值之前停止。
浮点步长与精度问题
使用浮点步长很方便,但有一个注意事项:浮点运算不是精确的。小的舍入误差可能会累积,偶尔产生意想不到的结果。
看这个例子:
import numpy as np
arr = np.arange(0, 1, 0.3)
print(arr)
# Output: [0. 0.3 0.6 0.9]
print(len(arr))
# Output: 4这看起来是正确的。但看看某些步长会发生什么:
import numpy as np
arr = np.arange(0, 1.0, 0.1)
print(len(arr))
# Output: 10
arr2 = np.arange(0.0, 1.0 + 1e-10, 0.1)
print(len(arr2))
# Output: 11由于浮点表示,二进制中 0.1 * 10 可能不完全等于 1.0。结果中的元素数量可能因具体值而相差一个。
最佳实践: 当你需要精确数量的等间距浮点值时,请改用 np.linspace()。仅当元素的精确数量不重要时,才对浮点序列使用 np.arange()。
负步长:倒计数
设置负的 step 来创建递减序列:
import numpy as np
arr = np.arange(10, 0, -1)
print(arr)
# Output: [10 9 8 7 6 5 4 3 2 1]浮点步长的工作方式相同:
import numpy as np
arr = np.arange(2.0, 0.0, -0.5)
print(arr)
# Output: [2. 1.5 1. 0.5]关键规则:步长方向必须与从 start 到 stop 的方向一致。如果 start < stop,步长必须为正。如果 start > stop,步长必须为负。搞错会产生空数组(在下面的错误部分有介绍)。
dtype参数
默认情况下,np.arange() 从你传入的参数推断数据类型。如果所有参数都是整数,你会得到一个整数数组。如果任何参数是浮点数,你会得到一个浮点数组。dtype 参数允许你覆盖这一行为:
import numpy as np
# Default: integers in, integers out
arr_int = np.arange(5)
print(arr_int.dtype)
# Output: int64
# Default: float step, float output
arr_float = np.arange(0, 5, 0.5)
print(arr_float.dtype)
# Output: float64
# Force float output from integer inputs
arr_forced = np.arange(5, dtype=np.float32)
print(arr_forced)
# Output: [0. 1. 2. 3. 4.]
print(arr_forced.dtype)
# Output: float32
# Force integer output (values get truncated)
arr_trunc = np.arange(0, 2, 0.5, dtype=int)
print(arr_trunc)
# Output: [0 0 1 1]注意最后一个例子:当你对浮点序列强制使用整数dtype时,每个值都被截断(而不是四舍五入)为整数。这可能产生重复值和意想不到的结果,所以要谨慎使用。
np.arange() vs range():何时使用哪个
Python的内置 range() 和NumPy的 np.arange() 都能生成数字序列,但它们服务于不同的目的。
| 特性 | range() | np.arange() |
|---|---|---|
| 返回类型 | range 对象(惰性迭代器) | numpy.ndarray(存储在内存中) |
| 支持浮点数 | 否(仅整数) | 是 |
| 向量化运算 | 否(需要转换为列表) | 是(直接数组操作) |
| 内存 | 非常低(按需生成) | 数组存储在内存中 |
| 迭代速度 | Python循环中快 | Python循环中较慢 |
| 计算速度 | 慢(必须先转换) | 快(向量化的C操作) |
| 在NumPy/SciPy中使用 | 必须用 np.array() 转换 | 直接使用 |
| 切片/索引结果 | 返回 range 对象 | 返回 ndarray |
何时使用 range(): 纯Python循环中需要索引,并且不对序列本身进行任何数学运算。
何时使用 np.arange(): 任何时候结果将用于数值计算、传递给NumPy/SciPy函数或需要包含浮点值。
import numpy as np
# range() for loop iteration
for i in range(5):
print(i, end=' ')
# Output: 0 1 2 3 4
print()
# np.arange() for vectorized math
x = np.arange(5)
print(np.sin(x))
# Output: [ 0. 0.84147098 0.90929743 0.14112001 -0.7568025 ]np.arange() vs np.linspace():何时使用哪个
两个函数都创建等间距值的数组,但它们定义间距的方式不同。
| 特性 | np.arange() | np.linspace() |
|---|---|---|
| 你指定的 | 步长 | 点的数量 |
| Stop值 | 默认排除 | 默认包含 |
| 浮点精度 | 可能产生意外的元素数 | 始终产生精确的数量 |
| 典型用途 | 整数序列、已知步长 | 范围内精确的点数 |
| 语法 | np.arange(start, stop, step) | np.linspace(start, stop, num) |
| 返回数量信息 | 否 | 可选(retstep=True) |
以下是一个清楚展示差异的对比示例:
import numpy as np
# arange: "give me values from 0 to 1, stepping by 0.2"
a = np.arange(0, 1, 0.2)
print(f"arange: {a} (length: {len(a)})")
# Output: arange: [0. 0.2 0.4 0.6 0.8] (length: 5)
# linspace: "give me exactly 6 values from 0 to 1"
b = np.linspace(0, 1, 6)
print(f"linspace: {b} (length: {len(b)})")
# Output: linspace: [0. 0.2 0.4 0.6 0.8 1. ] (length: 6)注意 np.linspace() 包含端点(1.0)并保证恰好6个值,而 np.arange() 在 1.0 之前停止,数量取决于浮点步长计算。
经验法则: 当步长重要时使用 np.arange()。当点的数量重要时使用 np.linspace()。
常见用例
循环索引和数组索引
import numpy as np
data = np.array([10, 20, 30, 40, 50])
indices = np.arange(len(data))
print(indices)
# Output: [0 1 2 3 4]
# Use for conditional selection
mask = indices % 2 == 0
print(data[mask])
# Output: [10 30 50]绘图的X轴值
import numpy as np
x = np.arange(0, 2 * np.pi, 0.01)
y = np.sin(x)
print(f"x has {len(x)} points, from {x[0]:.2f} to {x[-1]:.2f}")
# Output: x has 629 points, from 0.00 to 6.28
print(f"y ranges from {y.min():.4f} to {y.max():.4f}")
# Output: y ranges from -1.0000 to 1.0000你可以将 x 和 y 直接传递给matplotlib的 plt.plot(x, y) 来绘制平滑的正弦波。
创建网格坐标
import numpy as np
x = np.arange(0, 3)
y = np.arange(0, 4)
xx, yy = np.meshgrid(x, y)
print("xx:")
print(xx)
# Output:
# [[0 1 2]
# [0 1 2]
# [0 1 2]
# [0 1 2]]
print("yy:")
print(yy)
# Output:
# [[0 0 0]
# [1 1 1]
# [2 2 2]
# [3 3 3]]这种模式在图像处理、热力图和3D曲面图中被广泛使用。
生成基于时间的序列
import numpy as np
# Hours from 0 to 24 in 30-minute intervals
hours = np.arange(0, 24.5, 0.5)
print(f"Time points: {len(hours)}")
# Output: Time points: 49
print(hours[:6])
# Output: [0. 0.5 1. 1.5 2. 2.5]常见错误及修复方法
步长方向错误导致的空数组
np.arange() 最常见的错误是使用了方向错误的步长:
import numpy as np
# Trying to count down with a positive step
arr = np.arange(10, 0, 1)
print(arr)
# Output: []
# Trying to count up with a negative step
arr2 = np.arange(0, 10, -1)
print(arr2)
# Output: []两者都返回空数组,没有错误或警告。修复方法很简单——确保步长方向与从 start 到 stop 的方向一致:
import numpy as np
# Correct: counting down with negative step
arr = np.arange(10, 0, -1)
print(arr)
# Output: [10 9 8 7 6 5 4 3 2 1]零步长
步长为 0 永远无效,会引发错误:
import numpy as np
try:
arr = np.arange(0, 10, 0)
except ZeroDivisionError as e:
print(f"Error: {e}")
# Output: Error: division by zero意外的超大数组
由于 np.arange() 一次性在内存中创建整个数组,在大范围上使用非常小的步长可能消耗数GB的RAM:
import numpy as np
# This creates 10 billion elements -- do NOT run this
# arr = np.arange(0, 10, 0.000000001)
# Check the size first
count = int((10 - 0) / 0.000000001)
print(f"This would create {count:,} elements")
# Output: This would create 10,000,000,000 elements
print(f"Memory: ~{count * 8 / 1e9:.1f} GB (for float64)")
# Output: Memory: ~80.0 GB (for float64)在生成大型序列之前,务必先估算大小。
在RunCell中体验NumPy
如果你想交互式地尝试这些示例,并在学习NumPy的过程中获得AI驱动的帮助,请查看 RunCell (opens in a new tab)。RunCell是一个直接内置在Jupyter中的AI代理,帮助数据科学家编写、调试和优化代码。
不必在文档标签页和你的notebook之间来回切换,你可以让RunCell生成 np.arange() 示例、解释浮点精度行为,或帮助你为特定用例选择 arange 还是 linspace。它直接在你现有的Jupyter环境中运行,没有任何设置障碍——只需安装并在你的代码单元旁边开始提问。
当你第一次探索NumPy数组创建函数时,这特别有用,因为你可以实时迭代示例并立即看到结果。
常见问题
numpy arange返回什么?
np.arange() 返回一个包含等间距值的一维NumPy ndarray。与返回惰性迭代器的Python range() 不同,np.arange() 在内存中生成完整的数组。该数组支持向量化运算、广播和所有标准NumPy函数。
numpy arange可以使用浮点步长吗?
可以。与只接受整数的Python range() 不同,np.arange() 完全支持浮点数的start、stop和step值。例如,np.arange(0, 1, 0.1) 生成 [0.0, 0.1, 0.2, ..., 0.9]。但请注意,浮点舍入偶尔会导致结果比预期多一个或少一个元素。当你需要保证元素数量时,请使用 np.linspace()。
np.arange和np.linspace有什么区别?
np.arange() 接受步长并生成值直到达到stop值(不包含)。np.linspace() 接受你想要的点数并自动计算步长,默认包含端点。当你知道步长时使用 arange。当你知道需要多少个点时使用 linspace。
为什么np.arange返回空数组?
当步长方向与从start到stop的方向不匹配时,会返回空数组。例如,np.arange(10, 0, 1) 返回空数组,因为正步长无法从10向下移动到0。修复方法是使用负步长:np.arange(10, 0, -1)。
np.arange是否包含stop值?
stop值是不包含的——它永远不会出现在输出中。np.arange(0, 5) 返回 [0, 1, 2, 3, 4],而不是 [0, 1, 2, 3, 4, 5]。这与Python内置 range() 的行为一致。如果你需要包含端点,请使用 np.linspace() 并设置 endpoint=True(默认值)。
总结
np.arange() 是NumPy最常用的函数之一,这是有原因的:它是在Python中生成等间距数字数组的最快方法。以下是需要记住的要点总结:
- 一个参数(
np.arange(n))创建从0到n-1的整数。 - 两个参数(
np.arange(start, stop))定义范围,默认步长为1。 - 三个参数(
np.arange(start, stop, step))提供完全控制,包括浮点步长和用于递减序列的负步长。 dtype在你需要特定数据类型时覆盖自动类型推断。- 当步长重要时使用
np.arange()。当点的数量重要时使用np.linspace()。 - 注意浮点精度 —— 使用浮点步长的
np.arange()可能产生意外数量的元素。 - 空数组是由步长方向与start到stop方向不匹配造成的。
要交互式地实验NumPy数组,RunCell (opens in a new tab) 提供直接在Jupyter中的AI辅助编码,让你无需离开notebook即可测试 np.arange() 的各种变体并获得即时解释。