Автор оригинала: Pankaj Kumar.
NumPy-это наиболее часто используемая научная вычислительная библиотека Python. Он обеспечивает быстрый интерфейс Pythonic, в то же время используя гораздо более быстрый C++ под капотом для вычислений. Это гарантирует, что высокоуровневая читабельность и функции Pythonic по-прежнему присутствуют, делая фактические вычисления намного быстрее, чем это мог бы сделать чистый код Python.
Здесь мы рассмотрим структуру данных, за которой NumPy выполняет всю свою работу, и то, как мы могли бы преобразовать ее различными способами, аналогичными тому, как мы бы манипулировали другими структурами данных, похожими на массивы.
Объект массива NumPy
Чтобы объявить объект массива numpy, мы сначала импортируем библиотеку numpy
, после чего создаем экземпляр нашего вновь созданного массива с помощью функции np.array()
library.
Приведенный ниже фрагмент объявляет простой 1-мерный массив numpy:
>>> import numpy as np >>> a = np.array([1, 2, 3, 4]) >>> print(a) [1 2 3 4]
Каждый массив имеет следующие атрибуты:
ndim
(количество измерений)форма
(размер каждого измерения)размер
(общий размер массива)тип
(тип данных массива)
Элементы массива NumPy имеют один и тот же тип данных, в отличие от списков Python . В результате мы не можем заставить один массив numpy содержать несколько различных типов данных.
Объявление многомерного массива аналогично объявлению многомерного массива на любом другом языке с использованием соответствующей матрицы, представляющей весь массив.
# Declare a 2-Dimensional numpy array b = np.array([[1, 2, 3], [4, 5, 6]]) print("b -> ndim:", b.ndim) print("b -> shape:", b.shape) print("b -> size:", b.size) print("b -> dtype:", b.dtype)
Выход:
b -> ndim: 2 b -> shape: (2, 3) b -> size: 6 b -> dtype: dtype('int64')
Доступ к элементам массива NumPy
Подобно доступу к элементам списка и элементам массива в Python, доступ к массивам numpy осуществляется таким же образом.
Для доступа к отдельным элементам в многомерных массивах мы используем индексы, разделенные запятыми, для каждого измерения.
>>> b[0] array([1, 2, 3]) >>> b[1] array([4, 5, 6]) >>> b[-1] array([4, 5, 6]) >>> b[1, 1] 5
Нарезка массива NumPy
Опять же, подобно стандартной библиотеке Python, NumPy также предоставляет нам операцию среза для массивов numpy, с помощью которой мы можем получить доступ к срезу массива элементов, чтобы получить соответствующий подмассив.
>>> b[:] array([[1, 2, 3], [4, 5, 6]]) >>> b[:1] array([1, 2, 3])
На самом деле, это широко рекомендуемый способ использования массивов NumPy из-за высоко оптимизированного характера операций numpy. Поскольку собственные методы python довольно медленны по сравнению с ними, мы должны использовать только методы numpy для манипулирования массивами numpy. В результате чистые итерационные циклы Python и другие понимания списков не используются с numpy.
Другие способы создания массивов numpy
Мы можем использовать встроенный метод numpy range(n)
для построения 1-мерного массива, состоящего из чисел 0
к n-1
.
>>> c = np.arange(12) >>> print(c) [0 1 2 3 4 5 6 7 8 9 10 11] >>> c.shape (12,)
Использование random.randint(limit,)
генерирует случайный целочисленный массив со всеми элементами в диапазоне от 0 до limit
и размером N
, указанным в качестве аргумента ключевого слова.
>>> d = np.random.randint(10, size=6) >>> d array([7, 7, 8, 8, 3, 3]) >>> e = np.random.randint(10, size=(3,4)) >>> e array([[2, 2, 0, 5], [8, 9, 7, 3], [5, 7, 7, 0]])
Манипулирование массивами NumPy
NumPy предоставляет метод reshape()
, который можно использовать для изменения размеров массива numpy и изменения исходного массива на месте. Здесь мы показываем иллюстрацию использования reshape()
для изменения формы c
на (4, 3)
>>> c array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) >>> c.shape (12,) >>> c.reshape(4, 3) array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
Поскольку операции numpy предназначены для высокой оптимизации, любой подмассив, созданный из массива, по-прежнему содержит ссылку на исходный массив. Это означает, что если подмассив изменяется на месте, исходный массив также изменяется.
>>> f = e[:3, :2] >>> f array([[2, 2], [8, 9], [5, 7]]) >>> f[0,0] *= 3 >>> f array([[6, 2], [8, 9], [5, 7]]) >>> e array([[6, 2, 0, 5], [8, 9, 7, 3], [5, 7, 7, 0]])
Здесь исходный массив e
также изменяется при любом изменении среза подмассива f
. Это связано с тем, что срезы numpy возвращают только представление исходного массива.
Чтобы гарантировать, что исходный массив не будет изменен с помощью каких-либо изменений в срезе подмассива, мы используем метод numpy copy()
для создания копии массива и изменения клонированного объекта, вместо того, чтобы иметь дело со ссылкой на исходный объект.
В приведенном ниже фрагменте показано, как copy
решает эту проблему.
>>> e array([[6, 2, 0, 5], [8, 9, 7, 3], [5, 7, 7, 0]]) >>> f = e[:3, :2].copy() >>> f array([[6, 2], [8, 9], [5, 7]]) >>> f[0,0] = 100 >>> f array([[100, 2], [ 8, 9], [ 5, 7]]) >>> e # No change is reflected in the original array # We are safe! array([[6, 2, 0, 5], [8, 9, 7, 3], [5, 7, 7, 0]])
Вывод
В этой статье мы узнали о массивах numpy и некоторых элементарных операциях и манипуляциях с ними, включая их атрибуты, нарезку массивов, изменение формы и копирование.
Рекомендации
NumPy Docs