4. Создание массивов

Данная глава является лишь кратким обзором, поскольку способов создания массивов очень много, их описание и примеры использования вы найдете в разделе "Создание массивов" справочного руководства.

И так, массив может быть создан из обычного списка или кортежа Python с использованием функции array(). Причем тип полученного массива зависит от типа элементов последовательности:

>>> import numpy as np
>>>
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a.dtype
dtype('int32')
>>>
>>> a = np.array([1.1, 2.2, 3.3])
>>> a
array([ 1.1,  2.2,  3.3])
>>> a.dtype
dtype('float64')
>>>
>>> a = np.array([1 + 2j, 2 + 3j])
>>> a.dtype
dtype('complex128')

Необходимо помнить о том, что функции array() необходимо передавать именно последовательность, а не несколько аргументов.

>>> a = np.array(1, 2, 3)      #  Неправильно!!!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: only 2 non-keyword arguments accepted
>>>
>>> a = np.array([1, 2, 3])    #  Правильно
>>> a
array([1, 2, 3])
>>>
>>> a = np.array((1, 2, 3))    #  И так тоже правильно
>>> a
array([1, 2, 3])

Функция array() преобразует последовательности последовательностей в двумерные массивы, а последовательности последовательностей, которые тоже состоят из последовательностей в трехмерные массивы. То есть уровень вложенности исходной последовательности определяет размерность получаемого массива:

>>> a = np.array([[2, 4], [6, 8], [10, 12]])
>>> a
array([[ 2,  4],
       [ 6,  8],
       [10, 12]])
>>>
>>> b = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]])
>>> b
array([[[ 1,  2],
        [ 3,  4]],

       [[ 5,  6],
        [ 7,  8]],

       [[ 9, 10],
        [11, 12]]])
>>>
>>> a.ndim    #  Количество осей массива
2
>>> b.ndim
3

Функция array() так же позволяет определить тип данных массива.

>>> a = np.array([[2, 4], [6, 8], [10, 12]], dtype = complex )
>>> a
array([[  2.+0.j,   4.+0.j],
       [  6.+0.j,   8.+0.j],
       [ 10.+0.j,  12.+0.j]])
>>>
>>> a = np.array([[2, 4], [6, 8], [10, 12]], dtype = float )
>>> a
array([[  2.,   4.],
       [  6.,   8.],
       [ 10.,  12.]])

Очень часто возникает задача создания массива определенного размера, причем чем заполнен массив абсолютно неважно. В этом случае можно воспользоваться циклами или генераторами списков (кортежей), но NumPy для таких случаев предлагает более быстрые и менее затратные функции-заполнители.

Функция zeros заполняет массив нулями, функция ones - единицами, а функция empty - случайными числами, которые зависят от состояния памяти. По умолчанию, тип создаваемого массива - float64.

>>> np.zeros((3,3))
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
>>>
>>> np.ones((3,3))
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>>
>>> np.ones((3,3), dtype = complex)  #  Можно изменить тип массива
array([[ 1.+0.j,  1.+0.j,  1.+0.j],
       [ 1.+0.j,  1.+0.j,  1.+0.j],
       [ 1.+0.j,  1.+0.j,  1.+0.j]])
>>>
>>> np.empty([3, 3])
array([[ -2.56357799e-042,   1.00079160e-313,  -5.41541116e-070],
       [  1.51668796e-314,   0.00000000e+000,   1.48219694e-320],
       [  2.61270984e-262,   0.00000000e+000,   8.36469502e-316]])

Для создания последовательностей чисел NumPy предоставляет функцию arange, которая возвращает одномерные массивы:

>>> np.arange(10)    #  От 0 до указанного числа
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>
>>> np.arange(10, 20)    #  Диапазон
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>>
>>> np.arange(20, 100, 10)    #  Диапазон с заданным шагом
array([20, 30, 40, 50, 60, 70, 80, 90])
>>>
>>> np.arange(0, 1, 0.1)    #  Аргументы могут иметь тип float
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

Если функция arange используется с аргументами типа float, то предсказать количество элементов в возвращаемом массиве не так-то просто. Гораздо чаще возникает необходимость указания не шага изменения чисел в диапазоне, а количества чисел в заданном диапазоне. Функция linspace, так же как и arange принимает три аргумента, но третий аргумент, как раз и указывает количество чисел в диапазоне.

>>> np.linspace(0, 1, 5)
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ])
>>>
>>> np.linspace(0, 1, 7)
array([ 0.        ,  0.16666667,  0.33333333,  0.5       ,  0.66666667,
        0.83333333,  1.        ])
>>>
>>> np.linspace(10, 100, 5)
array([  10. ,   32.5,   55. ,   77.5,  100. ])

Функция linspace удобна еще и тем, что может быть использована для вычисления значений функций на заданном множестве точек:

>>> x = np.linspace( 0, 2*np.pi, 10 )
>>> x
array([ 0.        ,  0.6981317 ,  1.3962634 ,  2.0943951 ,  2.7925268 ,
        3.4906585 ,  4.1887902 ,  4.88692191,  5.58505361,  6.28318531])
>>>
>>> y1 = np.sin(x)
>>> y1
array([  0.00000000e+00,   6.42787610e-01,   9.84807753e-01,
         8.66025404e-01,   3.42020143e-01,  -3.42020143e-01,
        -8.66025404e-01,  -9.84807753e-01,  -6.42787610e-01,
        -2.44929360e-16])
>>>
>>> y2 = np.cos(x)
>>> y2
array([ 1.        ,  0.76604444,  0.17364818, -0.5       , -0.93969262,
       -0.93969262, -0.5       ,  0.17364818,  0.76604444,  1.        ])