在 NumPy RClass (`np.r_`) 中解释步长中的复数

Interpreting complex number in step size in NumPy RClass (`np.r_`)

这是一段代码:

np.concatenate(([3], [0]*5, np.arange(-1, 1.002, 2/9.0)))

# the above outputs 
array([ 3.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        , -1.        , -0.77777778, -0.55555556, -0.33333333,
       -0.11111111,  0.11111111,  0.33333333,  0.55555556,  0.77777778,
        1.        ])

虽然冗长,但很好理解。这是使用(滥用)使用的符号获得相同输出的另一种方法,其中复数作为步长。

np.r_[3, [0]*5, -1:1:10j]

# the above outputs
array([ 3.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        , -1.        , -0.77777778, -0.55555556, -0.33333333,
       -0.11111111,  0.11111111,  0.33333333,  0.55555556,  0.77777778,
        1.        ])

我试图了解第一种方法中的步长如何等同于第二种方法中的复数步长 (10j)。

2/9.0  == 10j  # how?

我在 scipy reference documentation 中读到 -1:1:10j 意味着我们要在 -1:1 之间产生 10 个值,包括两端。但是,10j 如何转化为 0.2222


P.S。我已经看过 ,但没有提供太多想法。

当您有 startstop(均包括)和 size 时,则 step 计算如下:

step = (stop - start) / (size - 1)

使用 start = -1stop = 1size = 2 你会得到 step = 2 和数组 [-1, 1]

使用 start = -1stop = 1size = 3 你会得到 step = 1 和数组 [-1, 0, 1]

使用切片 -1:1:10j 中的 start = -1stop = 1size = 10,您将得到 step = 2/9 和数组

[-1.        , -0.77777778, -0.55555556, -0.33333333, -0.11111111,
  0.11111111,  0.33333333,  0.55555556,  0.77777778,  1.        ]

注意:对于复数如10j,会先计算np.abs(10j)得到实数

r_ 文档的相关部分是:

However, if step is an imaginary number (i.e. 100j) then its integer portion is interpreted as a number-of-points desired and the start and stop are inclusive. In other words start:stop:stepj is interpreted as np.linspace(start, stop, step, endpoint=1) inside of the brackets.

这是在 numpy/lib/index_tricks.py 中的 中使用的符号技巧(mgrid 是另一个)。这不是一般的 numpy 或 python 技巧。使用 class 定义(不是函数)和自定义 __getitem__ 方法是关键。

关于数字的详细信息,请检查 np.linspace 的代码。 (MATLAB 有一个同名函数)。

也许这种与 arange 的比较会有助于给人一种直观的感觉。

In [65]: np.arange(-1,1.01,.2)                                                  
Out[65]: 
array([-1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01,
       -2.00000000e-01, -2.22044605e-16,  2.00000000e-01,  4.00000000e-01,
        6.00000000e-01,  8.00000000e-01,  1.00000000e+00])
In [66]: _.shape                                                                
Out[66]: (11,)
In [67]: np.linspace(-1,1,11)                                                   
Out[67]: array([-1. , -0.8, -0.6, -0.4, -0.2,  0. ,  0.2,  0.4,  0.6,  0.8,  1. ])

arange 产生了 11 个值,所以我们不得不在 linspace 中使用相同的大小数字。请注意,linspace 对终点的处理更好,从而使浮点值显示更清晰(两种情况下都不精确)。

如果我们改用 10,则间距是正确的 (.2222...*9=1.9999....)。要获得 10 个值,我们必须执行 9 次。或者把范围分成9个区间。

In [68]: np.linspace(-1,1,10)                                                   
Out[68]: 
array([-1.        , -0.77777778, -0.55555556, -0.33333333, -0.11111111,
        0.11111111,  0.33333333,  0.55555556,  0.77777778,  1.        ])

arange 浮点数比以整数开头的等效项更混乱:

In [70]: np.arange(-10,11,2)/10                                                 
Out[70]: array([-1. , -0.8, -0.6, -0.4, -0.2,  0. ,  0.2,  0.4,  0.6,  0.8,  1. ])