Интерпретация комплексного числа в размере шага в NumPy RClass (`np.r_`) - PullRequest
0 голосов
/ 14 апреля 2019

Вот кусок кода:

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.        ])

Хотя это многословно, это довольно понятно. И вот еще один способ получить тот же вывод, используя (ab) используемую запись с комплексным числом в качестве размера шага.

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 означает, что мы хотим получить 10 значений между -1:1, включая обе стороны. Но как это 10j переводится в 0.2222?

  • Какие-нибудь интуитивные идеи или объяснения?
  • Кроме того, каковы другие полезные примеры NumPy, которые мы можем сделать с таким выражением?

P.S. Я уже посмотрел на диапазон-строитель-r-ломтик-со-сложным-но-не воображаемым-шагом-величиной , но это не дает много идей.

Ответы [ 2 ]

2 голосов
/ 14 апреля 2019

Соответствующая часть документов r_:

Однако, если step является мнимым числом (т. Е. 100j), то его целочисленная часть интерпретируется как число точекжелательно и начало и остановка включительно.Другими словами start:stop:stepj интерпретируется как np.linspace(start, stop, step, endpoint=1) внутри скобок.

Это нотационный трюк, используемый в паре классов в numpy/lib/index_tricks.py (mgrid это другое).Это не общий numpy или трюк с питоном.Ключевым является использование определения 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. ])
1 голос
/ 14 апреля 2019

Если у вас есть start, stop (оба включены) и size, тогда step рассчитывается следующим образом:

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

С start = -1, stop = 1, size = 2 вы получите step = 2 и массив [-1, 1]

С start = -1, stop = 1, size = 3 вы получите step = 1 и массив [-1, 0, 1]

С start = -1, stop = 1, size = 10 из среза -1:1:10j вы получите 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), чтобы получить действительное число.

...