NumPy Ndarray: создание массива, генерация и типы данных / np 2
Основной элемент библиотеки 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() .
Чтобы узнать ассоциированный тип dtype , необходимо использовать атрибут dtype .
Примечание: результат dtype , shape и других может быть разным для разных операционных систем и дистрибутивов Python.
Только что созданный массив имеет одну ось, а его ранг равняется 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]])