Python – numpy.arange()

时间:2020-02-23 14:43:05  来源:igfitidea点击:

作为线性序列生成器,numpy.arange()函数用于在线性空间中以均匀步长生成数字序列。

这类似于另一个函数numpy.linspace(),该函数还生成具有均匀步长的线性序列。

让我们了解如何使用此函数生成不同的序列。

语法

格式:

array = numpy.arange(start, stop, step, dtype=None)

其中

  • start->范围的起点(包括在内),默认情况下设置为0。

  • stop->范围的终点(不包括)

  • step->序列的步长,默认设置为1。
    除零外,它可以是任何实数。

  • dtype->输出数组的类型。
    如果未给出dtype(或者以None形式提供),则将从其他输入参数的类型推断出数据类型。

让我们举一个简单的例子来理解这一点:

import numpy as np
 
a = np.arange(0.02, 2, 0.1, None)
 
print('Linear Sequence from 0.02 to 2:', a)
print('Length:', len(a))

这将生成一个从0.2(包括)到2(不包括)的线性序列,步长为0.1,因此序列中将有(2 – 0.2)/0.1 – 1 = 20个元素,这是结果的长度numpy数组。

输出

Linear Sequence from 0.02 to 2: [0.02 0.12 0.22 0.32 0.42 0.52 0.62 0.72 0.82 0.92 1.02 1.12 1.22 1.32
 1.42 1.52 1.62 1.72 1.82 1.92]
Length: 20

这是另一行代码,它使用" arange()"(默认步长为1)从0到9生成数字:

>>> np.arange(0, 10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

如果步长为0,则此序列无效,因为步长为0意味着您将范围除以0,这将引发" ZeroDivisionError"异常。

import numpy as np

# Invalid Step Size!
a = np.arange(0, 10, 0)

输出

ZeroDivisionError: division by zero

注意:此函数与numpy.linspace()略有不同,numpy.linspace()默认情况下包括序列计算的起点和终点。
它还不以步长为参数,而是仅采用序列中元素的数量。

一个简单的例子

现在,将所有这些放到一个简单的示例中,以演示由numpy.arange()生成的序列的线性。

下面的代码使用numpy.arange()在[0,20][0,10]之间绘制2个线性序列,以显示该序列生成的均匀性,因此所得数组是线性的。

import numpy as np
import matplotlib.pyplot as plt

y = np.zeros(5)

# Construct two linear sequences
# First one has a step size of 4 units
x1 = np.arange(0, 20, 4)

# Second one has a step size of 2 units
x2 = np.arange(0, 10, 2)

# Plot (x1, [0, 0, ..])
plt.plot(x1, y, 'o')

# Plot (x2, [0.5, 0.5, ..])
plt.plot(x2, y + 0.5, 'o')

# Set limit for y on the plot
plt.ylim([-0.5, 1])

plt.show()

如您所见,橙色点代表从0到10的线性序列,步长为2个单位,但是由于不包括10,因此该序列为" [0,2,4,4,6,8]"。
类似地,蓝点表示序列" [0、4、8、12、16]"。

numpy.arange()与range()

使用" numpy"模块的全部目的是确保我们执行的操作尽快完成,因为" numpy"是较低级C++代码的Python接口。

" numpy"中的许多运算都是矢量化的,这意味着当使用" numpy"执行任何数学运算时,这些运算会并行发生。
因此,对于大型数组和序列," numpy"产生最佳性能。

因此," numpy.arange()"比Python的本机" range()"函数生成相似的线性序列要快得多。

性能测试

我们不应该将numpy的向量化操作与Python循环一起插入。
由于代码正在使用本机Python进行迭代,因此这会极大地降低性能。

例如,以下代码片段显示了不应该使用numpy的方式。

for i in np.arange(100):
  pass

推荐的方法是直接使用numpy操作。

np.arange(100)

让我们使用Python的" timeit"模块测试性能差异。

import timeit
import numpy as np

# For smaller arrays
print('Array size: 1000')

# Time the average among 10000 iterations
print('range():', timeit.timeit('for i in range(1000): pass', number=10000))
print('np.arange():', timeit.timeit('np.arange(1000)', number=10000, setup='import numpy as np'))

# For large arrays
print('Array size: 1000000')

# Time the average among 10 iterations
print('range():', timeit.timeit('for i in range(1000000): pass', number=10))
print('np.arange():', timeit.timeit('np.arange(1000000)', number=10, setup='import numpy as np'))

输出

Array size: 1000
range(): 0.18827421900095942
np.arange(): 0.015803234000486555
Array size: 1000000
range(): 0.22560399899884942
np.arange(): 0.011916546000065864

如您所见,numpy.arange()对于大型序列特别有效。
它的大小几乎是普通Python代码的20倍(!!),大小仅为1000000,这只能在较大的数组上更好地扩展。

因此,在使用更大的数组时,程序员应该一致选择numpy.arange()。

对于较小的阵列,当性能差异不大时,可以在两种方法中的任何一种中使用。