返回值及参数np.arange()
数值模拟arange()
是基于数值范围的数组创建例程之一。它创建一个实例ndarray
和均匀分布的值并返回对其的引用。
您可以使用以下四个参数定义数组中包含的值的间隔、它们之间的空间以及它们的类型arange()
:
numpy.arange([start, ]stop, [step, ], dtype=None) -> numpy.ndarray
前三个参数确定值的范围,而第四个参数指定元素的类型:
-
start
是个数字(整数或小数)定义数组中的第一个值。
-
stop
是定义数组末尾且不包含在数组中的数字。
-
step
是定义数组中每两个连续值之间的间距(差异)的数字,默认为1
.
-
dtype
是输出数组元素的类型,默认为没有任何.
step
不能为零。否则,你会得到一个ZeroDivisionError
。你无法离开任何地方start
如果增量或减量是0
.
If dtype
被省略,arange()
将尝试从数组元素的类型中推断出数组元素的类型start
, stop
, 和step
.
您可以找到有关参数和返回值的更多信息arange()
在里面官方文档.
范围参数np.arange()
NumPy 的参数arange()
定义数组中包含的值对应于数字参数start
, stop
, 和step
。你必须通过最后一个其中。
以下示例将向您展示如何arange()
行为取决于参数的数量及其值。
提供所有范围参数
使用 NumPy 例程时,必须首先导入 NumPy:
>>>>>> import numpy as np
现在,您已导入 NumPy,并准备好应用arange()
.
让我们看一下如何使用 NumPy 的第一个示例arange()
:
>>>>>> np.arange(start=1, stop=10, step=3)
array([1, 4, 7])
在这个例子中,start
是1
。因此,得到的数组的第一个元素是1
. step
是3
,这就是为什么你的第二个值是 1+3,即4
,而数组中的第三个值是 4+3,等于7
.
按照这种模式,下一个值将是10
(7+3),但计数必须结束前 stop
已达到,所以不包括这一点。
你可以通过start
, stop
, 和step
也作为位置参数:
>>>>>> np.arange(1, 10, 3)
array([1, 4, 7])
此代码示例与前一个示例等效,但比前一个更简洁。
的价值stop
不包含在数组中。这就是为什么你可以用不同的方法获得相同的结果stop
价值观:
>>>>>> np.arange(1, 8, 3)
array([1, 4, 7])
此代码示例返回与前两个具有相同值的数组。使用任何值都可以获得相同的结果stop
严格大于7
且小于或等于10
.
但是,如果你使stop
比...更棒10
,那么计数将在之后结束10
到达了:
>>>>>> np.arange(1, 10.1, 3)
array([ 1., 4., 7., 10.])
在本例中,您将获得包含四个元素的数组,其中包括10
.
请注意,与前一个示例不同,此示例创建了一个浮点数数组。那是因为你没有定义dtype
, 和arange()
为你推演了。您将在本文后面了解更多相关信息。
您可以在下图中看到这三个示例的图形表示:
start
显示为绿色,stop
为红色,同时step
数组中包含的值是蓝色的。
从上图可以看出,前两个示例有三个值(1
, 4
, 和7
)算了。他们不允许10
被包括。在第三个例子中,stop
大于10
,并且它包含在结果数组中。
提供两个范围参数
你可以省略step
。在这种情况下,arange()
使用其默认值1
。以下两个语句是等效的:
>>>>>> np.arange(start=1, stop=10, step=1)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(start=1, stop=10)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
第二个声明较短。step
,默认为1
,是通常直观的预期。
使用arange()
随着增量1
是实践中非常常见的情况。同样,您可以使用位置参数更简洁地编写前面的示例start
和stop
:
>>>>>> np.arange(1, 10)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
这是一种直观且简洁的调用方式arange()
。在本例中使用关键字参数并不能真正提高可读性。
笔记:如果您提供两个位置参数,则第一个是start
第二个是stop
.
提供一个范围参数
您必须提供至少一个论点到arange()
。更准确地说,您必须提供start
.
但如果你省略会发生什么stop
?如何arange()
知道什么时候停止计数吗?在这种情况下,数组开始于0
并在值之前结束start
到达了!再次,默认值step
是1
.
换句话说,arange()
假设您已经提供了stop
(代替start
) 然后start
是0
和step
是1
.
让我们看一个例子,你想用以下方式开始一个数组0
,增加值1
,并在此之前停止10
:
>>>>>> np.arange(start=0, stop=10, step=1)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(0, 10, 1)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(start=0, stop=10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(0, 10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
这些代码示例没问题。它们的工作方式如前面的示例所示。还有一种更短、更简洁、但仍然直观的方法来完成同样的事情。您可以只提供一个位置参数:
>>>>>> np.arange(10) # Stop is 10, start is 0, and step is 1!
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
这是创建从零开始并以 1 为增量的 NumPy 数组的最常用方法。
笔记:单个参数定义计数停止的位置。输出数组开始于0
并且增量为1
.
如果您尝试明确提供stop
没有start
,那么你会得到一个TypeError
:
>>>>>> np.arange(stop=10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: arange() missing required argument 'start' (pos 1)
你收到错误是因为arange()
不允许你明确地避免对应的第一个参数start
。如果您提供单个参数,那么它必须是start
, 但arange()
将使用它来定义计数停止的位置。
提供否定论据
如果您为start
或两者start
和stop
,并有一个积极的step
, 然后arange()
将以与所有正参数相同的方式工作:
>>>>>> np.arange(-5, -1)
array([-5, -4, -3, -2])
>>> np.arange(-8, -2, 2)
array([-8, -6, -4])
>>> np.arange(-5, 6, 4)
array([-5, -1, 3])
此行为与前面的示例完全一致。计数从以下值开始start
,重复递增step
,并在此之前结束stop
到达了。
倒数
有时您需要一个数组,其值从左到右递减。在这种情况下,您可以使用arange()
为负值step
,并用一个start
比...更棒stop
:
>>>>>> np.arange(5, 1, -1)
array([5, 4, 3, 2])
>>> np.arange(7, 0, -3)
array([7, 4, 1])
在此示例中,请注意以下模式:获取的数组以第一个参数的值开始,并递减step
朝向第二个参数的值。
在最后的声明中,start
是7
,结果数组以此值开始。step
是-3
所以第二个值为 7+(−3),即4
。第三个值是 4+(−3),或者1
。自此停止计数stop
(0
) 在下一个值 (-2
).
您可以在下图中看到此示例的图形表示:
再次,start
显示为绿色,stop
为红色,同时step
数组中包含的值是蓝色的。
这次,箭头显示从右到左的方向。那是因为start
大于stop
, step
是负数,你基本上是在倒数。
前面的示例产生与以下相同的结果:
>>>>>> np.arange(1, 8, 3)[::-1]
array([7, 4, 1])
>>> np.flip(np.arange(1, 8, 3))
array([7, 4, 1])
然而,具有负值的变体step
更加优雅简洁。
获取空数组
在几种边缘情况下,您可以使用以下命令获取空 NumPy 数组:arange()
。这些都是常见的例子numpy.ndarray
没有任何元素。
如果您为start
和stop
,那么你会得到一个空数组:
>>>>>> np.arange(2, 2)
array([], dtype=int64)
这是因为计数在值之前结束stop
到达了。由于值start
等于stop
,它也无法被访问并包含在结果数组中。
不寻常的情况之一是当start
大于stop
和step
为正,或者当start
小于stop
和step
是负数:
>>>>>> np.arange(8, 2, 1)
array([], dtype=int64)
>>> np.arange(2, 8, -1)
array([], dtype=int64)
正如您所看到的,这些示例的结果是空数组,not有错误。
数据类型np.arange()
NumPy 数组中元素的类型是使用它们的一个重要方面。当与arange()
,您可以使用参数指定元素的类型dtype
.
笔记:以下是有关 NumPy 数组中包含的元素类型的一些要点:
- NumPy 数组中的所有元素都属于同一类型,称为数据类型(短缺数据类型).
- NumPy 数据类型比 Python 的内置数字类型提供更多的粒度。
- 在某些情况下,NumPy dtype 具有与 Python 内置类型名称相对应的别名。
- 通常,NumPy 例程可以接受 Python 数字类型,反之亦然。
- 一些 NumPy 数据类型具有依赖于平台的定义。
如果您想了解有关 NumPy 数组的数据类型的更多信息,请阅读官方文档.
你可以随意省略dtype
。在这种情况下,arange()
将尝试推断结果数组的数据类型。这取决于类型start
, stop
, 和step
,如以下示例所示:
>>>>>> x = np.arange(5)
>>> x
array([0, 1, 2, 3, 4])
>>> x.dtype
dtype('int64')
>>> x.itemsize # In bytes
8
这里,有一个论点(5
) 定义值的范围。它的类型是int
。这就是数组的 dtype 的原因x
将是 NumPy 提供的整数类型之一。在这种情况下,NumPy 选择int64
默认为数据类型。这是 64 位(8 字节)整数类型。
上一示例中的数组与此等效:
>>>>>> x = np.arange(5, dtype=int)
>>> x
array([0, 1, 2, 3, 4])
>>> x.dtype
dtype('int64')
论据dtype=int
不参考Pythonint
。它翻译为 NumPyint64
或者简单地np.int
.
NumPy 为您提供了几种整数固定大小的数据类型,它们在内存和限制方面有所不同:
-
np.int8
:8 位有符号整数(来自-128
到127
)
-
np.uint8
:8 位无符号整数(来自0
到255
)
-
np.int16
:16 位有符号整数(来自-32768
到32767
)
-
np.uint16
:16 位无符号整数(来自0
到65535
)
-
np.int32
:32 位有符号整数(来自-2**31
到2**31-1
)
-
np.uint32
:32 位无符号整数(来自0
到2**32-1
)
-
np.int64
:64 位有符号整数(来自-2**63
到2**63-1
)
-
np.uint64
:64 位无符号整数(来自0
到2**64-1
)
如果您想要数组元素的其他整数类型,则只需指定dtype
:
>>>>>> x = np.arange(5, dtype=np.int32)
>>> x
array([0, 1, 2, 3, 4], dtype=int32)
>>> x.dtype
dtype('int32')
>>> x.itemsize # In bytes
4
现在,生成的数组具有与前一种情况相同的值,但元素的类型和大小不同。论据dtype=np.int32
(或者dtype='int32'
) 强制每个元素的大小x
为 32 位(4 字节)。
当您的参数是十进制数而不是整数时,dtype 将是某种 NumPy 浮点类型,在这种情况下float64
:
>>>>>> y = np.arange(5.0)
>>> y
array([0., 1., 2., 3., 4.])
>>> y.dtype
dtype('float64')
最后四个示例中元素的值相同,但数据类型不同。
一般来说,当您至少提供一个浮点参数时arange()
,即使其他参数是整数,结果数组也将具有浮点元素:
>>>>>> np.arange(1, 5.1)
array([1., 2., 3., 4., 5.])
>>> np.arange(1, 5.1).dtype
dtype('float64')
>>> np.arange(0, 9, 1.5)
array([0. , 1.5, 3. , 4.5, 6. , 7.5])
>>> np.arange(0, 9, 1.5).dtype
dtype('float64')
在上面的例子中,start
是一个整数,但 dtype 是np.float64
因为stop
或者step
是浮点数。
如果您指定dtype
, 然后arange()
将尝试生成一个包含所提供数据类型的元素的数组:
>>>>>> y = np.arange(5, dtype=float)
>>> y
array([0., 1., 2., 3., 4.])
>>> y.dtype
dtype('float64')
论据dtype=float
这里翻译为 NumPyfloat64
, 那是np.float
。它不参考Pythonfloat
。固定大小的别名float64
是np.float64
和np.float_
.
当您需要具有较低精度和大小(以字节为单位)的浮点数据类型时,您可以显式指定:
>>>>>> z = np.arange(5, dtype=np.float32)
>>> z
array([0., 1., 2., 3., 4.], dtype=float32)
>>> z.dtype
dtype('float32')
使用dtype=np.float32
(或者dtype='float32'
) 使数组的每个元素z
32 位(4 字节)大。每个元素的大小y
是 64 位(8 字节):
>>>>>> y.itemsize # In bytes
8
>>> z.itemsize # In bytes
4
元素之间的区别y
和z
,并且一般在np.float64
和np.float32
,是使用的内存和精度:第一个比后者更大且更精确。
在许多情况下,您不会注意到这种差异。然而,有时这很重要。例如,TensorFlow用途float32 和 int32。同样,当您处理图像时,甚至使用较小的类型,例如 uint8.
什么时候step
不是整数,结果可能会不一致浮点运算的局限性.
超越简单范围np.arange()
您可以方便地组合arange()
与运算符(如+
, -
, *
, /
, **
等)和其他 NumPy 例程(例如绝对值()或者罪()) 产生输出值的范围:
>>>>>> x = np.arange(5)
>>> x
array([0, 1, 2, 3, 4])
>>> 2**x
array([ 1, 2, 4, 8, 16])
>>> y = np.arange(-1, 1.1, 0.5)
>>> y
array([-1. , -0.5, 0. , 0.5, 1. ])
>>> np.abs(y)
array([1. , 0.5, 0. , 0.5, 1. ])
>>> z = np.arange(10)
>>> np.sin(z)
array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ,
-0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849])
当您想要在 Matplotlib 中创建绘图.
如果您需要多维数组,那么您可以组合arange()
和.reshape()或类似的函数和方法:
>>>>>> a = np.arange(6).reshape((2, 3))
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> a.shape
(2, 3)
>>> a.ndim
2
这就是您可以获得ndarray
带有元素的实例[0, 1, 2, 3, 4, 5]
和重塑将其转为二维数组。
相对比range
和np.arange()
Python有一个内置类range
,类似于 NumPyarange()
在某种程度上。range
和np.arange()
具有与应用和性能相关的重要区别。您会看到它们的差异和相似之处。
两者之间的主要区别在于range
是一个内置的Python类, 尽管arange()
是属于第三方库 (NumPy) 的函数。
另外,他们的目的也不一样!一般来说,range
当你需要时更适合迭代使用Python for 循环。如果你想创建一个 NumPy 数组,并在后台应用快速循环,那么arange()
是一个更好的解决方案。
参数和输出
两个都range
和arange()
具有定义所获得数字范围的相同参数:
即使在以下情况下,您也可以类似地应用这些参数:start
和stop
是平等的。
然而,当与range
:
- 您必须提供整数参数。否则,你会得到一个
TypeError
.
- 您无法指定生成数字的类型。总是如此
int
.
range
和arange()
它们的返回类型也有所不同:
-
range
创建此类的一个实例,该实例具有与其他序列相同的功能(例如列表和元组),例如隶属度、串联、重复、切片、比较、长度检查等。
-
arange()
返回 NumPy 的实例ndarray
.
创建序列
您可以申请range
创建一个实例list
或者tuple
在预定义范围内均匀分布的数字。你可能会发现理解力特别适合此目的。
然而,创建和操作 NumPy 数组通常是快点和更优雅与使用列表或元组相比。
我们来比较一下创建的性能列表使用针对等效 NumPy 的理解ndarray
和arange()
:
>>>>>> import timeit
>>> n = 1
>>> timeit.timeit(f'x = [i**2 for i in range({n})]')
>>> timeit.timeit(f'x = np.arange({n})**2', setup='import numpy as np')
对不同的值重复此代码n
在我的机器上得到以下结果:
Size: n
|
Time Per Loop: range
|
Time Per Loop: arange()
|
Ratio |
1 |
497 ns |
1.14 µs |
0.41 |
10 |
2.24 µs |
1.28 µs |
1.74 |
100 |
20.0 µs |
1.37 µs |
14.6 |
1,000 |
211 µs |
2.92 µs |
72.3 |
这些结果可能会有所不同,但显然,您可以比列表更快地创建 NumPy 数组,但长度非常小的序列除外。 (该应用程序通常会带来额外的性能优势!)
这是因为 NumPy 在 C 级别执行许多操作,包括循环。此外,NumPy 针对向量的使用进行了优化,并避免了一些与 Python 相关的开销。
Pythonfor
循环
如果您需要在 Python 中迭代值for
循环,然后range
通常是更好的解决方案。根据Python官方文档:
的优点range
键入常规内容list
或者tuple
那是一个range
对象将始终占用相同(少量)的内存,无论它表示的范围大小如何(因为它只存储start
, stop
和step
根据需要计算单个项目和子范围的值)。 (来源)
range
通常比arange()
当在Python中使用时for
循环,尤其是当有可能很快跳出循环时。这是因为range
根据需要,以惰性方式生成数字,一次一个。
相比之下,arange()
生成开头的所有数字。
欲了解更多信息range
,你可以检查Python range() 函数(指南)和官方文档.