Spec-Zone.ru › NumPy 2.0

Как создавать массивы с равномерно распределёнными значениями

Существует несколько функций NumPy, похожих по применению, но дающих немного разные результаты, что может вызвать путаницу, если не ясно, когда и как их использовать. Следующее руководство призвано перечислить эти функции и описать их рекомендуемое использование.

Функции, упомянутые здесь, это:

  • numpy.linspace
  • numpy.arange
  • numpy.geomspace
  • numpy.logspace
  • numpy.meshgrid
  • numpy.mgrid
  • numpy.ogrid

Одномерные области (интервалы)

linspace против arange

И numpy.linspace, и numpy.arange предоставляют способы разбиения интервала (одномерной области) на подынтервалы одинаковой длины. Эти разбиения будут различаться в зависимости от выбранных начальной и конечной точек и шага (длины подынтервалов).

  • Используйте numpy.arange, если вам нужны целочисленные шаги.

    numpy.arange опирается на размер шага для определения количества элементов в возвращаемом массиве, исключая конечную точку. Это определяется через аргумент step функции arange.

    Пример:

    >>> np.arange(0, 10, 2)  # np.arange(start, stop, step)
    array([0, 2, 4, 6, 8])
    

    Аргументы start и stop должны быть целыми или вещественными, но не комплексными числами. numpy.arange аналогична встроенной функции Python range.

    Неточности с плавающей точкой могут сделать результаты arange с числами с плавающей точкой непонятными. В этом случае следует использовать numpy.linspace вместо неё.

  • Используйте numpy.linspace , если вы хотите, чтобы конечная точка была включена в результат, или если вы используете размер шага, который не является целым числом.

    numpy.linspace может включать конечную точку и определяет размер шага из аргумента num, который указывает количество элементов в возвращаемом массиве.

    Включение конечной точки определяется необязательным булевым аргументом endpoint, который по умолчанию равен True. Обратите внимание, что выбор endpoint=False изменит вычисление размера шага и последующий вывод функции.

    Пример:

    >>> np.linspace(0.1, 0.2, num=5)  # np.linspace(start, stop, num)
    array([0.1  , 0.125, 0.15 , 0.175, 0.2  ])
    >>> np.linspace(0.1, 0.2, num=5, endpoint=False)
    array([0.1, 0.12, 0.14, 0.16, 0.18])
    

    numpy.linspace также может быть использована с комплексными аргументами:

    >>> np.linspace(1+1.j, 4, 5, dtype=np.complex64)
    array([1.  +1.j  , 1.75+0.75j, 2.5 +0.5j , 3.25+0.25j, 4.  +0.j  ],
          dtype=complex64)
    

Другие примеры

  1. Неожиданные результаты могут возникнуть, если значения с плавающей точкой используются в качестве step в numpy.arange. Чтобы этого избежать, убедитесь, что все преобразования чисел с плавающей точкой происходят после вычисления результатов. Например, замените

    >>> list(np.arange(0.1,0.4,0.1).round(1))
    [0.1, 0.2, 0.3, 0.4]  # endpoint should not be included!
    

    на

    >>> list(np.arange(1, 4, 1) / 10.0)
    [0.1, 0.2, 0.3]  # expected result
    
  2. Обратите внимание, что

    >>> np.arange(0, 1.12, 0.04)
    array([0.  , 0.04, 0.08, 0.12, 0.16, 0.2 , 0.24, 0.28, 0.32, 0.36, 0.4 ,
           0.44, 0.48, 0.52, 0.56, 0.6 , 0.64, 0.68, 0.72, 0.76, 0.8 , 0.84,
           0.88, 0.92, 0.96, 1.  , 1.04, 1.08, 1.12])
    

    и

    >>> np.arange(0, 1.08, 0.04)
    array([0.  , 0.04, 0.08, 0.12, 0.16, 0.2 , 0.24, 0.28, 0.32, 0.36, 0.4 ,
           0.44, 0.48, 0.52, 0.56, 0.6 , 0.64, 0.68, 0.72, 0.76, 0.8 , 0.84,
           0.88, 0.92, 0.96, 1.  , 1.04])
    

    Они различаются из-за численного шума. При использовании значений с плавающей точкой возможно, что 0 + 0.04 * 28 < 1.12, и поэтому 1.12 попадает в интервал. На самом деле, это именно тот случай:

    >>> 1.12/0.04
    28.000000000000004
    

    Но 0 + 0.04 * 27 >= 1.08, так что 1.08 исключается:

    >>> 1.08/0.04
    27.0
    

    В качестве альтернативы, вы можете использовать np.arange(0, 28)*0.04, что всегда даст вам точный контроль над конечной точкой, поскольку она целочисленная:

    >>> np.arange(0, 28)*0.04
    array([0.  , 0.04, 0.08, 0.12, 0.16, 0.2 , 0.24, 0.28, 0.32, 0.36, 0.4 ,
           0.44, 0.48, 0.52, 0.56, 0.6 , 0.64, 0.68, 0.72, 0.76, 0.8 , 0.84,
           0.88, 0.92, 0.96, 1.  , 1.04, 1.08])
    

geomspace и logspace

numpy.geomspace аналогична numpy.linspace, но с числами, равномерно распределенными на логарифмической шкале (геометрическая прогрессия). Конечная точка включена в результат.

Пример:

>>> np.geomspace(2, 3, num=5)
array([2.        , 2.21336384, 2.44948974, 2.71080601, 3.        ])

numpy.logspace аналогична numpy.geomspace, но начальная и конечная точки задаются как логарифмы (по умолчанию основание 10):

>>> np.logspace(2, 3, num=5)
array([ 100.        ,  177.827941  ,  316.22776602,  562.34132519, 1000.        ])

В линейном масштабе последовательность начинается с base ** start (base в степени start) и заканчивается base ** stop:

>>> np.logspace(2, 3, num=5, base=2)
array([4.        , 4.75682846, 5.65685425, 6.72717132, 8.        ])

N-мерные области

N-мерные области могут быть разбиты на сетки. Это можно сделать, используя одну из следующих функций.

meshgrid

Цель numpy.meshgrid — создание прямоугольной сетки из набора одномерных координатных массивов.

Даны массивы:

>>> x = np.array([0, 1, 2, 3])
>>> y = np.array([0, 1, 2, 3, 4, 5])

meshgrid создаст два координатных массива, которые можно использовать для генерации пар координат, определяющих эту сетку.:

>>> xx, yy = np.meshgrid(x, y)
>>> xx
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3]])
>>> yy
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3],
       [4, 4, 4, 4],
       [5, 5, 5, 5]])

>>> import matplotlib.pyplot as plt
>>> plt.plot(xx, yy, marker='.', color='k', linestyle='none')
../_images/meshgrid_plot.png

mgrid

numpy.mgrid может использоваться как сокращение для создания сетки. Это не функция, но при индексировании возвращает многомерную сетку.

>>> xx, yy = np.meshgrid(np.array([0, 1, 2, 3]), np.array([0, 1, 2, 3, 4, 5]))
>>> xx.T, yy.T
(array([[0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3]]),
 array([[0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5]]))

>>> np.mgrid[0:4, 0:6]
array([[[0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3]],

       [[0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5]]])

ogrid

Аналогично numpy.mgrid, numpy.ogrid возвращает открытую многомерную сетку. Это означает, что при индексировании только одно измерение каждого возвращаемого массива больше 1. Это позволяет избежать повторения данных и, таким образом, экономит память, что часто желательно.

Эти разреженные координатные сетки предназначены для использования с векторизацией. При использовании всех координат в выражении векторизация по-прежнему приводит к массиву результатов с полными измерениями.

>>> np.ogrid[0:4, 0:6]
[array([[0],
        [1],
        [2],
        [3]]), array([[0, 1, 2, 3, 4, 5]])]

Все три описанных здесь метода могут быть использованы для вычисления значений функции на сетке.

>>> g = np.ogrid[0:4, 0:6]
>>> zg = np.sqrt(g[0]**2 + g[1]**2)
>>> g[0].shape, g[1].shape, zg.shape
((4, 1), (1, 6), (4, 6))
>>> m = np.mgrid[0:4, 0:6]
>>> zm = np.sqrt(m[0]**2 + m[1]**2)
>>> np.array_equal(zm, zg)
True

© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/user/how-to-partition.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API