Основной элемент библиотеки NumPy — объект ndarray
(что значит N-размерный массив). Этот объект является многомерным однородным массивом с заранее заданным количеством элементов. Однородный — потому что практически все объекты в нем одного размера или типа. На самом деле, тип данных определен другим объектом NumPy, который называется dtype
(тип-данных). Каждый ndarray
ассоциирован только с одним типом dtype
.
Количество размерностей и объектов массива определяются его размерностью (shape
), кортежем N-положительных целых чисел. Они указывают размер каждой размерности. Размерности определяются как оси, а количество осей — как ранг.
Еще одна странность массивов NumPy в том, что их размер фиксирован, а это значит, что после создания объекта его уже нельзя поменять. Это поведение отличается от такового у списков Python, которые могут увеличиваться и уменьшаться в размерах.
Простейший способ определить новый объект ndarray
— использовать функцию array()
, передав в качестве аргумента Python-список элементов.
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
Можно легко проверить, что новый объект — это ndarray
, передав его функции type()
.
>>> type(a)
<type 'numpy.ndarray'>
Чтобы узнать ассоциированный тип dtype
, необходимо использовать атрибут dtype
.
Примечание: результат
dtype
,shape
и других может быть разным для разных операционных систем и дистрибутивов Python.
>>> a.dtype
dtype('int64')
Только что созданный массив имеет одну ось, а его ранг равняется 1
, то есть его форма — (3,1)
. Для получения этих значений из массива необходимо использовать следующие атрибуты: ndim
— для осей, size
— для длины массива, shape
— для его формы.
>>> a.ndim
1
>>> a.size
3
>>> a.shape
(3,)
Это был пример простейшего одномерного массива. Но функциональность массивов может быть расширена и до нескольких размерностей. Например, при определении двумерного массива 2×2:
>>> b = np.array([[1.3, 2.4],[0.3, 4.1]])
>>> b.dtype
dtype('float64')
>>> b.ndim
2
>>> b.size
4
>>> b.shape
(2, 2)
Ранг этого массива — 2, поскольку у него 2 оси, длина каждой из которых также равняется 2.
Еще один важный атрибут — itemsize
. Он может быть использован с объектами ndarray
. Он определяет размер каждого элемента массива в байтах, а data
— это буфер, содержащий все элементы массива. Второй атрибут пока не используется, потому что для получения данных из массива применяется механизм индексов, речь о котором подробно пойдет в следующих разделах.
>>> b.itemsize
8
>>> b.data
<read-write buffer for 0x0000000002D34DF0, size 32, offset 0 at
0x0000000002D5FEA0>
Создание массива
Есть несколько вариантов создания массива. Самый распространенный — список из списков, выступающий аргументом функции array()
.
>>> c = np.array([[1, 2, 3],[4, 5, 6]])
>>> c
array([[1, 2, 3],
[4, 5, 6]])
Функция array()
также может принимать кортежи и последовательности кортежей.
>>> d = np.array(((1, 2, 3),(4, 5, 6)))
>>> d
array([[1, 2, 3],
[4, 5, 6]])
Она также может принимать последовательности кортежей и взаимосвязанных списков.
>>> e = np.array([(1, 2, 3), [4, 5, 6], (7, 8, 9)])
>>> e
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Типы данных
Пока что рассматривались только значения простого целого числа и числа с плавающей запятой, но массивы NumPy сделаны так, чтобы включать самые разные типы данных. Например, можно включать строки:
Типы данных, поддерживаемые NumPy
Тип данных | Описание |
---|---|
bool | Булевы значения (True или False ) хранятся в виде байтов |
int | Тип по умолчанию — целое число (то же, что long в C; обычно int64 или int32 ) |
intc | Идентичный int в C (обычно int32 или int64 ) |
intp | Целое число для использования в качестве индексов (то же, что и size_t в C, обычно int32 или int64 ) |
int8 | Байт (от — 128 до 127) |
int16 | Целое число (от -32768 до 32767) |
int32 | Целое число (от -2147483648 до 2147483647) |
int64 | Целое число (от -9223372036854775808 до 9223372036854775807) |
uint8 | Целое число без знака (от 0 до 255) |
uint16 | Целое число без знака (от 0 до 65535) |
uint32 | Целое число без знака (от 0 до 4294967295) |
uint64 | Целое число без знака (от 0 до 18446744073709551615) |
float | Обозначение float64 |
float16 | Число с плавающей точкой половинной точности; бит на знак, 5-битная экспонента, 10-битная мантисса |
float32 | Число с плавающей точкой единичной точности; бит на знак, 8-битная экспонента, 23-битная мантисса |
float64 | Число с плавающей точкой двойной точности; бит на знак, 11-битная экспонента, 52-битная мантисса |
complex | Обозначение complex128 |
complex64 | Комплексное число, представленное двумя 32-битными float (с действительной и мнимой частями) |
complex128 | Комплексное число, представленное двумя 64-битными float (с действительной и мнимой частями) |
Параметр dtype
Функция array()
не принимает один аргумент. На примерах видно, что каждый объект ndarray
ассоциирован с объектом dtype
, определяющим тип данных, которые будут в массиве. По умолчанию функция array()
можно ассоциировать самый подходящий тип в соответствии со значениями в последовательностях списков или кортежей. Их можно определить явно с помощью параметра dtype
в качестве аргумента.
Например, если нужно определить массив с комплексными числами в качестве значений, необходимо использовать параметр dtype
следующим образом:
>>> f = np.array([[1, 2, 3],[4, 5, 6]], dtype=complex)
>>> f
array([[ 1.+0.j, 2.+0.j, 3.+0.j],
[ 4.+0.j, 5.+0.j, 6.+0.j]])
Функции генерации массива
Библиотека NumPy предоставляет набор функций, которые генерируют ndarray
с начальным содержимым. Они создаются с разным значениями в зависимости от функции. Это очень полезная особенность. С помощью всего одной строки кода можно сгенерировать большой объем данных.
Функция zeros()
, например, создает полный массив нулей с размерностями, определенными аргументом shape
. Например, для создания двумерного массива 3×3, можно использовать:
>>> np.zeros((3, 3))
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
А функция ones()
создает массив, состоящий из единиц.
>>> np.ones((3, 3))
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
По умолчанию две функции создают массивы с типом данных float64
. Полезная фишка — arrange()
. Она генерирует массивы NumPy с числовыми последовательностями, которые соответствуют конкретным требованиям в зависимости от переданных аргументов. Например, для генерации последовательности значений между 0 и 10, нужно передать всего один аргумент — значение, которое закончит последовательность.
>>> np.arange(0, 10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Если в начале нужен не ноль, то необходимо обозначить уже два аргумента: первый и последний.
>>> np.arange(4, 10)
array([4, 5, 6, 7, 8, 9])
Также можно сгенерировать последовательность значений с точным интервалом между ними. Если определено и третье значение в arrange()
, оно будет представлять собой промежуток между каждым элементом.
>>> np.arange(0, 12, 3)
array([0, 3, 6, 9])
Оно может быть и числом с плавающей точкой.
>>> np.arange(0, 6, 0.6)
array([ 0. , 0.6, 1.2, 1.8, 2.4, 3. , 3.6, 4.2, 4.8, 5.4])
Пока что в примерах были только одномерные массивы. Для генерации двумерных массивов все еще можно использовать функцию arrange()
, но вместе с reshape()
. Она делит линейный массив на части способом, который указан в аргументе shape
.
>>> np.arange(0, 12).reshape(3, 4)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Похожая на arrange()
функция — linspace()
. Она также принимает в качестве первых двух аргументов первое и последнее значения последовательности, но третьим аргументом является не интервал, а количество элементов, на которое нужно разбить последовательность.
>>> np.linspace(0,10,5)
array([ 0. , 2.5, 5. , 7.5, 10. ])
Еще один способ получения массива — заполнение его случайными значениями. Это можно сделать с помощью функции random()
из модуля numpy.random
. Эта функция генерирует массив с тем количеством элементов, которые указаны в качестве аргумента.
>>> np.random.random(3)
array([ 0.78610272, 0.90630642, 0.80007102])
Полученные числа будут отличаться с каждым запуском. Для создания многомерного массива, нужно передать его размер в виде аргумента.
>>> np.random.random((3,3))
array([[ 0.07878569, 0.7176506 , 0.05662501],
[ 0.82919021, 0.80349121, 0.30254079],
[ 0.93347404, 0.65868278, 0.37379618]])