Советы

Основы работы с NumPy

Все курсы > Программирование на Питоне > Занятие 9

Основы работы с NumPy

Первое знакомство с библиотекой NumPy (Numerical Python) состоялось на двенадцатом занятии вводного курса. Затем мы несколько раз использовали эту библиотеку при построении моделей. Пришло время посвятить ее функционалу отдельный раздел.

Библиотека Numpy является основой для многих других библиотек в Питоне, например, Pandas, Matplotlib, scikit-learn или scikit-image. Главный объект библиотеки — массив Numpy (Numpy array). О нем мы поговорим сегодня.

  • На следующем занятии мы изучим математические операции над массивами, а через одно — рассмотрим работу со случайными числами.
  • Массив Numpy — это многомерный массив (ndarray, n-dimensional array) данных, над которыми можно быстро и эффективно выполнять множество математических, статистических, логических и других операций.
  • Приведу пример массива с нулевым измерением, а также одно-, двух- и трехмерного массивов.

Основы работы с NumPy

  1. Теперь посмотрим как работать с этими массивами на практике.
  2. Откроем ноутбук к этому занятию⧉
  3. Вначале нужно импортировать библиотеку Numpy.
# библиотеку Numpy принято сокращать как npimport numpy as np

Рассмотрим два варианта создания одномерного массива.

Во-первых, массив можно создать с помощью функции np.array(), которой мы передаем, например, список или кортеж элементов.

  • # создадим массив из списка
  • arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  • arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  1. # или кортежа
  2. arr = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
  3. arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Кроме того, можно воспользоваться функцией np.arange(). Эта функция, как и функция range(), с которой мы уже знакомы, создает последовательность элементов. Обязательным параметром является верхняя граница, которая не входит в последовательность.

  • # создадим последовательность из 10 элементов
  • arr = np.arange(10)
  • arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Нижняя граница и шаг обязательными не являются.

  1. # зададим нижнюю и верхнюю границу и шаг
  2. arr = np.arange(2, 10, 2)
  3. print(arr)

Отличие range() от функции np.arange() заключается в том, что первая не допускает использования типа float.

# создадим список с помощью функций range() и list()list(range(2, 5.5, 0.5))

Основы работы с NumPy

При этом в массиве Numpy тип float вполне может использоваться.

array([2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ])

Как вы уже вероятно обратили внимание, в массивах тип данных определяется автоматически. При этом при создании массива мы можем задать этот параметр принудительно.

  • # создадим массив с элементами типа float
  • arr_f = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], float)
  • print(arr_f)
  • # тип данных можно посмотреть через атрибут dtype
  • print(arr_f.dtype)
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]float64

Обратите внимание, в отличие, например, от списков, чаще всего в массивах содержатся элементы только одного типа (в частности, int или float).

Возьмем массив, который мы создали выше.

Важным свойством (или как правильнее говорить атрибутом) массива является количество его измерений, ndim. В данном случае это одномерный массив или вектор.

  1. Теперь, с помощью атрибута shape, посмотрим на количество элементов в каждом измерении.
  2. Обратите внимание, даже когда массив одномерный, результат атрибута shape выводится в виде кортежа (на это указывают круглые скобки и запятая после цифры четыре).
  3. Атрибут size показывает общее количество элементов во всех измерениях.
# пока что у нас одно измерение, в котором четыре элементаarr.size

Как уже было сказано выше, атрибут dtype показывает тип данных отдельного элемента.

# в нашем случае — это целое число длиной 64 битаarr.dtype

Атрибут itemsize позволяет узнать размер в байтах (один байт состоит из 8 бит) одного элемента. В нашем случае, элемент (число) состоит из 64 бит, что составляет восемь байтов.

# 64 / 8 бит = 8 байтовarr.itemsize

Общий размер массива в байтах (nbytes) позволяет понять, в частности, поместится ли массив в оперативную память компьютера.

# у нас четыре элемента по восемь байтов или 32 байтаarr.nbytes

Тот же результат можно получить, умножив общее количество элементов на размер одного элемента в байтах.

Как уже было сказано, ndarray (массив Numpy) — это многомерный массив. Давайте еще раз взглянем на массивы с различными измерениями, добавив только что изученные атрибуты этих массивов.

Основы работы с NumPy

Теперь подробнее поговорим про размерность. Измерения (dimensions) создаются за счёт вложения одного массива в другой с помощью квадратных скобок []. Начнем с массива с нулевой размерностью.

Массив с нулевой размерностью — это число (скаляр) и квадратных скобок не имеет.

arr_0D = np.array(42)arr_0D

Посмотрим на свойства этого массива.

  • print(arr_0D.ndim)
  • print(arr_0D.shape)
  • print(arr_0D.size)

Атрибут shape показывает отсутствие размерности, а size указывает на один элемент в массиве.

Вложив несколько массивов с нулевой размерностью в квадратные скобки, мы получим одномерный массив или вектор.

arr_1D = np.array([1, 2, 3])arr_1D

Снова воспользуемся атрибутами массива.

  1. print(arr_1D.ndim)
  2. print(arr_1D.shape)
  3. print(arr_1D.size)

Поместив во вторые квадратные скобки, например, два одномерных массива, мы получим двумерный массив или матрицу.

  • # с точки зрения синтаксиса — это просто вложенные списки
  • arr_2D = np.array([[1, 2, 3], [4, 5, 6]])
  • arr_2D
array([[1, 2, 3],       [4, 5, 6]])

Посмотрим на свойства.

  1. print(arr_2D.ndim)
  2. print(arr_2D.shape)
  3. print(arr_2D.size)

Атрибут size двумерного массива более интуитивно понятен. В данном случае два элемента одного измерения умножены на три элемента второго.

Добавлю, что с точки зрения Numpy матрица с одной строкой или одним столбцом — это разные объекты. Начнем с матрицы, которая имеет три вектора по одному элементу.

column = np.array([[1], [2], [3]])column
# посмотрим на размерностьcolumn.shape

Теперь наоборот, создадим матрицу с одной строкой, в которой три элемента.

row = np.array([[1, 2, 3]])row
# размерность будет инойrow.shape

Теперь создадим трехмерный массив, внутри которого будут два двумерных массива 2 х 3. Общее количество элементов будет равно двенадцати (2 х 2 х 3). Визуально это можно представить как стэк (наложение) двух матриц.

Основы работы с NumPy

При этом, вместо того чтобы вручную прописывать все 12 значений, мы последовательно воспользуемся функцией np.arange() и методом np.reshape().

arr_3D = np.arange(12).reshape(2, 2, 3)arr_3D
  • array([[[ 0,  1,  2],
  •         [ 3,  4,  5]],
  •        [[ 6,  7,  8],
  •         [ 9, 10, 11]]])

Функция np.arange(), как мы уже видели выше, создаст одномерный массив из 12 элементов, а метод np.reshape() распределит их по измерениям. Выведем атрибуты.

  1. print(arr_3D.ndim)
  2. print(arr_3D.shape)
  3. print(arr_3D.size)

Обратите внимание, атрибут shape сначала выводит размерность внешнего измерения, в нем две матрицы. Далее в каждую матрицу вложены два одномерных вектора. В каждом векторе по три элемента.

  • Аналогичным образом создаются четырехмерные массивы, а также массивы с большим количеством измерений.
  • Добавлю, что в математике n-мерный массив называется тензором, а числа (скаляры), векторы и матрицы являются его частными случаями для нуля, одного и двух измерений соответственно.

Основы работы с NumPy

Иногда бывает полезно создать массив, все элементы которого равны нулю. Для этого используется функция np.zeros().

# ей мы можем передать одно значение для создания одномерного массиваnp.zeros(5)
array([0., 0., 0., 0., 0.])
# или кортеж из чисел для указания количества нулей в каждом измеренииnp.zeros((2, 3))
array([[0., 0., 0.],       [0., 0., 0.]])

В тех случаях когда нужно создать массив, заполненный единицами, можно воспользоваться функцией np.ones().

# создадим трехмерный массивnp.ones((2, 2, 3))
array([[[1., 1., 1.],        [1., 1., 1.]],       [[1., 1., 1.],        [1., 1., 1.]]])

Функция np.full() создает массив, заполненный заданным значением.

# создадим матрицу 2 х 3 и заполним ее цифрой четыреnp.full((2, 3), 4)
array([[4, 4, 4],       [4, 4, 4]])

В отличие от предыдущих инструментов, функция np.empty() возвращает массив заданной размерности, но без инициализации его значений. Другими словами, пустой массив.

# создадим пустую матрицу 3 х 2np.empty((3, 2))
array([[4.65552661e-310, 0.00000000e+000],       [0.00000000e+000, 0.00000000e+000],       [0.00000000e+000, 0.00000000e+000]])

NumPy quickstart#

You’ll need to know a bit of Python. For a refresher, see the Python
tutorial.

To work the examples, you’ll need matplotlib installed
in addition to NumPy.

Learner profile

This is a quick overview of arrays in NumPy. It demonstrates how n-dimensional
((n>=2)) arrays are represented and can be manipulated. In particular, if
you don’t know how to apply common functions to n-dimensional arrays (without
using for-loops), or if you want to understand axis and shape properties for
n-dimensional arrays, this article might be of help.

Learning Objectives

After reading, you should be able to:

  • Understand the difference between one-, two- and n-dimensional arrays in
    NumPy;
  • Understand how to apply some linear algebra operations to n-dimensional
    arrays without using for-loops;
  • Understand axis and shape properties for n-dimensional arrays.

NumPy’s main object is the homogeneous multidimensional array. It is a
table of elements (usually numbers), all of the same type, indexed by a
tuple of non-negative integers. In NumPy dimensions are called axes.

For example, the array for the coordinates of a point in 3D space,
[1, 2, 1], has one axis. That axis has 3 elements in it, so we say
it has a length of 3. In the example pictured below, the array has 2
axes. The first axis has a length of 2, the second axis has a length of
3.

[[1., 0., 0.], [0., 1., 2.]]

NumPy’s array class is called ndarray. It is also known by the alias
array. Note that numpy.array is not the same as the Standard
Python Library class array.array, which only handles one-dimensional
arrays and offers less functionality. The more important attributes of
an ndarray object are:

Читайте также:  Pet-project: что это такое, примеры, какой пет-проект написать

ndarray.ndim

the number of axes (dimensions) of the array.

ndarray.shape

the dimensions of the array. This is a tuple of integers indicating
the size of the array in each dimension. For a matrix with n rows
and m columns, shape will be (n,m). The length of the
shape tuple is therefore the number of axes, ndim.

ndarray.size

the total number of elements of the array. This is equal to the
product of the elements of shape.

ndarray.dtype

an object describing the type of the elements in the array. One can
create or specify dtype’s using standard Python types. Additionally
NumPy provides types of its own. numpy.int32, numpy.int16, and
numpy.float64 are some examples.

ndarray.itemsize

the size in bytes of each element of the array. For example, an
array of elements of type float64 has itemsize 8 (=64/8),
while one of type complex32 has itemsize 4 (=32/8). It is
equivalent to ndarray.dtype.itemsize.

ndarray.data

the buffer containing the actual elements of the array. Normally, we
won’t need to use this attribute because we will access the elements
in an array using indexing facilities.

>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.ndim
2
>>> a.dtype.name
'int64'
>>> a.itemsize
8
>>> a.size
15
>>> type(a)

>>> b = np.array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)

There are several ways to create arrays.

For example, you can create an array from a regular Python list or tuple
using the array function. The type of the resulting array is deduced
from the type of the elements in the sequences.

>>> import numpy as np
>>> a = np.array([2, 3, 4])
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int64')
>>> b = np.array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64')

A frequent error consists in calling array with multiple arguments,
rather than providing a single sequence as an argument.

>>> a = np.array(1, 2, 3, 4) # WRONG
Traceback (most recent call last):

TypeError: array() takes from 1 to 2 positional arguments but 4 were given
>>> a = np.array([1, 2, 3, 4]) # RIGHT

array transforms sequences of sequences into two-dimensional arrays,
sequences of sequences of sequences into three-dimensional arrays, and
so on.

>>> b = np.array([(1.5, 2, 3), (4, 5, 6)])
>>> b
array([[1.5, 2. , 3. ],
[4. , 5. , 6. ]])

The type of the array can also be explicitly specified at creation time:

>>> c = np.array([[1, 2], [3, 4]], dtype=complex)
>>> c
array([[1.+0.j, 2.+0.j],
[3.+0.j, 4.+0.j]])

Often, the elements of an array are originally unknown, but its size is
known. Hence, NumPy offers several functions to create
arrays with initial placeholder content. These minimize the necessity of
growing arrays, an expensive operation.

The function zeros creates an array full of zeros, the function
ones creates an array full of ones, and the function empty
creates an array whose initial content is random and depends on the
state of the memory. By default, the dtype of the created array is
float64, but it can be specified via the key word argument dtype.

Пакет numpy предоставляет $n$-мерные однородные массивы (все элементы одного типа); в них нельзя вставить или удалить элемент в произвольном месте. В numpy реализовано много операций над массивами в целом. Если задачу можно решить, произведя некоторую последовательность операций над массивами, то это будет столь же эффективно, как в C или matlab — львиная доля времени тратится в библиотечных функциях, написанных на C.

Замечание. Модуль numpy.random не рассматривается целенаправленно. Вместо него рассмотри модуль scipy.stats, который больше подходит под вероятностно-статистические задачи.

1. Одномерные массивы¶

1.1 Типы массивов, атрибуты¶

Можно преобразовать список в массив.

a = np.array([0, 2, 1])
a, type(a)

(array([0, 2, 1]), numpy.ndarray)

print печатает массивы в удобной форме.

Класс ndarray имеет много методов.

set(dir(a)) — set(dir(object))

{'T',
'__abs__',
'__add__',
'__and__',
'__array__',
'__array_finalize__',
'__array_function__',
'__array_interface__',
'__array_prepare__',
'__array_priority__',
'__array_struct__',
'__array_ufunc__',
'__array_wrap__',
'__bool__',
'__complex__',
'__contains__',
'__copy__',
'__deepcopy__',
'__delitem__',
'__divmod__',
'__float__',
'__floordiv__',
'__getitem__',
'__iadd__',
'__iand__',
'__ifloordiv__',
'__ilshift__',
'__imatmul__',
'__imod__',
'__imul__',
'__index__',
'__int__',
'__invert__',
'__ior__',
'__ipow__',
'__irshift__',
'__isub__',
'__iter__',
'__itruediv__',
'__ixor__',
'__len__',
'__lshift__',
'__matmul__',
'__mod__',
'__mul__',
'__neg__',
'__or__',
'__pos__',
'__pow__',
'__radd__',
'__rand__',
'__rdivmod__',
'__rfloordiv__',
'__rlshift__',
'__rmatmul__',
'__rmod__',
'__rmul__',
'__ror__',
'__rpow__',
'__rrshift__',
'__rshift__',
'__rsub__',
'__rtruediv__',
'__rxor__',
'__setitem__',
'__setstate__',
'__sub__',
'__truediv__',
'__xor__',
'all',
'any',
'argmax',
'argmin',
'argpartition',
'argsort',
'astype',
'base',
'byteswap',
'choose',
'clip',
'compress',
'conj',
'conjugate',
'copy',
'ctypes',
'cumprod',
'cumsum',
'data',
'diagonal',
'dot',
'dtype',
'dump',
'dumps',
'fill',
'flags',
'flat',
'flatten',
'getfield',
'imag',
'item',
'itemset',
'itemsize',
'max',
'mean',
'min',
'nbytes',
'ndim',
'newbyteorder',
'nonzero',
'partition',
'prod',
'ptp',
'put',
'ravel',
'real',
'repeat',
'reshape',
'resize',
'round',
'searchsorted',
'setfield',
'setflags',
'shape',
'size',
'sort',
'squeeze',
'std',
'strides',
'sum',
'swapaxes',
'take',
'tobytes',
'tofile',
'tolist',
'tostring',
'trace',
'transpose',
'var',
'view'}

В $n$-мерном случае возвращается кортеж размеров по каждой координате.

size — это полное число элементов в массиве; len — размер по первой координате (в 1-мерном случае это то же самое).

numpy предоставляет несколько типов для целых (int16, int32, int64) и чисел с плавающей точкой (float32, float64).

a.dtype, a.dtype.name, a.itemsize

(dtype('int64'), 'int64', 8)

Массив чисел с плавающей точкой.

b = np.array([0., 2, 1])
b.dtype

c = np.array([0, 2, 1], dtype=np.float64)
print(c)

print(c.dtype)
print(c.astype(int))
print(c.astype(str))

float64
[0 2 1]
['0.0' '2.0' '1.0']

Индексировать массив можно обычным образом.

Массивы — изменяемые объекты.

Массивы, разумеется, можно использовать в for циклах. Но при этом теряется главное преимущество numpy — быстродействие. Всегда, когда это возможно, лучше использовать операции над массивами как едиными целыми.

Упражнение: создайте numpy-массив, состоящий из первых пяти простых чисел, выведите его тип и размер.

Решение:

arr = np.array([2, 3, 5, 7, 11])
print(arr)
print(arr.shape)
print(arr.dtype)

Массивы, заполненные нулями или единицами. Часто лучше сначала создать такой массив, а потом присваивать значения его элементам.

a = np.zeros(3)
b = np.ones(3, dtype=np.int64)
print(a)
print(b)

Если нужно создать массив, заполненный нулями, длины и типа другого массива, то можно использовать конструкцию

Функция arange подобна range. Аргументы могут быть с плавающей точкой. Следует избегать ситуаций, когда (конец-начало)/шаг — целое число, потому что в этом случае включение последнего элемента зависит от ошибок округления. Лучше, чтобы конец диапазона был где-то посредине шага.

a = np.arange(0, 9, 2)
print(a)

b = np.arange(0., 9, 2)
print(b)

Последовательности чисел с постоянным шагом можно также создавать функцией linspace. Начало и конец диапазона включаются; последний аргумент — число точек.

a = np.linspace(0, 8, 5)
print(a)

Упражнение: создайте и выведите последовательность чисел от 10 до 20 с постоянным шагом, длина последовательности — 21.

Решение:

arr = np.linspace(10, 20, 21)
print(arr)

[10. 10.5 11. 11.5 12. 12.5 13. 13.5 14. 14.5 15. 15.5 16. 16.5
17. 17.5 18. 18.5 19. 19.5 20. ]

Последовательность чисел с постоянным шагом по логарифмической шкале от $10^0$ до $10^1$.

b = np.logspace(0, 1, 5)
print(b)

[ 1. 1.77827941 3.16227766 5.62341325 10. ]

Арифметические операции проводятся поэлементно.

# Quickstart tutorial

Before reading this tutorial you should know a bit of Python. If you would like to refresh your memory, take a look at the Python tutorialopen in new window.

If you wish to work the examples in this tutorial, you must also have some software installed on your computer. Please see https://scipy.org/install.htmlopen in new window for instructions.

# The Basics

NumPy’s main object is the homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of non-negative integers. In NumPy dimensions are called axes.

For example, the coordinates of a point in 3D space [1, 2, 1] has one axis. That axis has 3 elements in it, so we say it has a length of 3. In the example pictured below, the array has 2 axes. The first axis has a length of 2, the second axis has a length of 3.

[[ 1., 0., 0.], [ 0., 1., 2.]]

NumPy’s array class is called ndarray. It is also known by the alias array. Note that numpy.array is not the same as the Standard Python Library class array.array, which only handles one-dimensional arrays and offers less functionality. The more important attributes of an ndarray object are:

ndarray.ndim

  • the number of axes (dimensions) of the array.

ndarray.shape

  • the dimensions of the array. This is a tuple of integers indicating the size of the array in each dimension. For a matrix with n rows and m columns, shape will be (n,m). The length of the shape tuple is therefore the number of axes, ndim.
Читайте также:  Что такое Work-life balance

ndarray.size

  • the total number of elements of the array. This is equal to the product of the elements of shape.

ndarray.dtype

  • an object describing the type of the elements in the array. One can create or specify dtype’s using standard Python types. Additionally NumPy provides types of its own. numpy.int32, numpy.int16, and numpy.float64 are some examples.

ndarray.itemsize

  • the size in bytes of each element of the array. For example, an array of elements of type float64 has itemsize 8 (=64/8), while one of type complex32 has itemsize 4 (=32/8). It is equivalent to ndarray.dtype.itemsize.

ndarray.data

  • the buffer containing the actual elements of the array. Normally, we won’t need to use this attribute because we will access the elements in an array using indexing facilities.

# An example

>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.ndim
2
>>> a.dtype.name
'int64'
>>> a.itemsize
8
>>> a.size
15
>>> type(a)

>>> b = np.array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)

# Array Creation

There are several ways to create arrays.

For example, you can create an array from a regular Python list or tuple using the array function. The type of the resulting array is deduced from the type of the elements in the sequences.

>>> import numpy as np
>>> a = np.array([2,3,4])
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int64')
>>> b = np.array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64')

A frequent error consists in calling array with multiple numeric arguments, rather than providing a single list of numbers as an argument.

>>> a = np.array(1,2,3,4) # WRONG
>>> a = np.array([1,2,3,4]) # RIGHT

array transforms sequences of sequences into two-dimensional arrays, sequences of sequences of sequences into three-dimensional arrays, and so on.

>>> b = np.array([(1.5,2,3), (4,5,6)])
>>> b
array([[ 1.5, 2. , 3. ], [ 4. , 5. , 6. ]])

The type of the array can also be explicitly specified at creation time:

>>> c = np.array( [ [1,2], [3,4] ], dtype=complex )
>>> c
array([[ 1.+0.j, 2.+0.j], [ 3.+0.j, 4.+0.j]])

Often, the elements of an array are originally unknown, but its size is known. Hence, NumPy offers several functions to create arrays with initial placeholder content. These minimize the necessity of growing arrays, an expensive operation.

The function zeros creates an array full of zeros, the function ones creates an array full of ones, and the function empty creates an array whose initial content is random and depends on the state of the memory. By default, the dtype of the created array is float64.

Учебное пособие по NumPy: простое руководство на основе примеров

Библиотека NumPy — это популярная библиотека
Python, используемая для приложений научных вычислений, и является
аббревиатурой от «Numerical Python».

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

Чтобы сделать это как можно быстрее, NumPy
написан на C и Python.

В этой статье мы дадим краткое введение в стек NumPy и увидим, как
библиотеку NumPy можно использовать для выполнения множества
математических задач.

Преимущества NumPy

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

  1. NumPy чрезвычайно быстр по сравнению с ядром Python благодаря
    интенсивному использованию расширений C.
  2. Многие продвинутые библиотеки Python, такие как Scikit-Learn, Scipy
    и Keras, широко используют библиотеку NumPy. Поэтому, если вы
    планируете продолжить карьеру в области науки о данных или машинного
    обучения, NumPy — очень хороший инструмент для освоения.
  3. NumPy поставляется с множеством встроенных функций, которые в ядре
    Python потребуют значительного количества настраиваемого кода.

Что касается последнего пункта, взгляните на следующий скрипт:

x = [2, 3, 4, 5, 6]
y = [a + 2 for a in x]

Здесь, чтобы добавить 2 к каждому элементу в списке x , мы должны
пройти весь список и добавить 2 к каждому элементу индивидуально. Теперь
посмотрим, как мы можем выполнить ту же задачу с библиотекой NumPy:

import numpy as np
nums = np.array([2, 3, 4, 5, 6])
nums2 = nums + 2

Вы можете увидеть, как легко добавить скалярное значение к каждому
элементу в списке через NumPy. Он не только читается, но и быстрее по
сравнению с предыдущим кодом.

Это лишь верхушка айсберга, на самом деле библиотека NumPy способна
выполнять гораздо более сложные операции в мгновение ока. Давайте
рассмотрим некоторые из этих операций.

NumPy Операции

Прежде чем мы сможем выполнять какие-либо операции NumPy, нам необходимо
установить пакет NumPy. Чтобы установить пакет NumPy, вы можете
использовать установщик pip. Для установки выполните следующую команду:

$ pip install numpy

В противном случае, если вы используете Python через дистрибутив
Anaconda, вы можете вместо этого выполнить следующую команду:

$ conda install numpy

Теперь, когда NumPy установлен, давайте посмотрим на некоторые из
наиболее распространенных операций библиотеки.

Создание массива NumPy

Массивы NumPy являются строительными блоками большинства операций NumPy.
Массивы NumPy можно разделить на два типа: одномерные массивы и
двумерные массивы.

Есть несколько способов создать массив NumPy. В этом разделе мы обсудим
некоторые из них.

Метод массива

Чтобы создать одномерный массив NumPy, мы можем просто передать список
Python в метод array Посмотрите следующий сценарий в качестве примера:

import numpy as np
x = [2, 3, 4, 5, 6]
nums = np.array([2, 3, 4, 5, 6])
type(nums)

В приведенном выше скрипте мы сначала импортировали библиотеку NumPy как
np и создали список x . Затем мы передали этот список array
библиотеки NumPy. Наконец, мы распечатали тип массива, что привело к
следующему выводу:

numpy.ndarray

Если бы вы распечатали nums на экране, вы бы увидели, что он
отображается следующим образом:

array([2, 3, 4, 5, 6])

Чтобы создать двумерный массив, вы можете передать список списков
array как показано ниже:

nums = np.array([[2,4,6], [8,10,12], [14,16,18]])

Результатом приведенного выше сценария является матрица, в которой
каждый внутренний список внешнего списка становится строкой. Количество
столбцов равно количеству элементов в каждом внутреннем списке. Выходная
матрица будет выглядеть так:

array([[ 2, 4, 6],
[ 8, 10, 12],
[14, 16, 18]])

Метод аранжа

Другой часто используемый метод создания массива NumPy — это метод
arange Этот метод принимает начальный индекс массива, конечный индекс
и размер шага (который является необязательным). Взгляните на следующий
пример:

nums = np.arange(2, 7)

Достаточно просто, правда? Приведенный выше сценарий вернет массив NumPy
размером 5 с элементами 2, 3, 4, 5 и 6. Помните, что arange возвращает
массив, который начинается с начального индекса и заканчивается на один
индекс меньше, чем конечный индекс. Вывод этого кода выглядит так:

array([2, 3, 4, 5, 6])

Теперь давайте добавим к нашему массиву размер шага 2 и посмотрим, что
произойдет:

nums = np.arange(2, 7, 2)

Теперь результат выглядит так:

array([2, 4, 6])

Вы можете видеть, что массив начинается с 2, за ним следует размер шага
2 и заканчивается на 6, что на единицу меньше конечного индекса.

Метод нулей

Помимо создания настраиваемых массивов с вашими предварительно
заполненными данными, вы также можете создавать массивы NumPy с более
простым набором данных. Например, вы можете использовать zeros для
создания массива всех нулей, как показано ниже:

zeros = np.zeros(5)

Приведенный выше скрипт вернет одномерный массив из 5 нулей.
Распечатайте zeros и вы должны увидеть следующее:

array([0., 0., 0., 0., 0.])

Точно так же, чтобы создать двумерный массив, вы можете передать
количество строк и столбцов zeros , как показано ниже:

zeros = np.zeros((5, 4))

Приведенный выше скрипт вернет двумерный массив из 5 строк и 4 столбцов:

array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])

Единственный метод

Точно так же вы можете создавать одномерные и двухмерные массивы всех
единиц, используя ones следующим образом:

ones = np.ones(5)

array([1., 1., 1., 1., 1.])

И снова для двумерного массива попробуйте следующий код:

ones = np.ones((5, 4))

Теперь, если вы распечатаете ones на экране, вы должны увидеть
следующий двумерный массив:

[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]

Метод линспейса

Еще один очень полезный метод создания массивов NumPy — это метод
linspace Этот метод принимает три аргумента: начальный индекс,
конечный индекс и количество чисел с линейным интервалом, которое вы
хотите между указанным диапазоном. Например, если первый индекс равен 1,
последний индекс равен 10 и вам нужно 10 элементов с равным интервалом в
этом диапазоне, вы можете использовать linspace следующим образом:

lin = np.linspace(1, 10, 10)

Читайте также:  ТОП-7 книг по Swift и iOS-разработке в 2023 году

Вывод вернет целые числа от 1 до 10:

array([1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])

Теперь давайте попробуем создать массив из 20 линейно расположенных
элементов от 1 до 10. Выполните следующий скрипт:

lin = np.linspace(1, 10, 20)

В результате получится следующий массив:

array([ 1. , 1.47368421, 1.94736842, 2.42105263, 2.89473684,
3.36842105, 3.84210526, 4.31578947, 4.78947368, 5.26315789,
5.73684211, 6.21052632, 6.68421053, 7.15789474, 7.63157895,
8.10526316, 8.57894737, 9.05263158, 9.52631579, 10. ])

Обратите внимание, что результат может выглядеть как матрица, но на
самом деле это одномерный массив. Из-за проблемы с интервалом элементы
отображались в несколько строк.

Метод глаза

Метод eye можно использовать для создания единичной
матрицы , которая может
быть очень полезна для выполнения множества операций в линейной алгебре.
Единичная матрица — это матрица с нулями в строках и столбцах, кроме
диагонали. Значения по диагонали — все единицы. Создадим единичную
матрицу 4×4 с помощью метода eye

idn = np.eye(4)

Результирующая матрица выглядит так:

array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])

Случайный метод

Часто вам нужно создавать массивы со случайными числами. Для этого вы
можете использовать функцию rand модуля random Вот простой пример
функции rand

random = np.random.rand(2, 3)

Приведенный выше сценарий возвращает матрицу из 2 строк и 3 столбцов.
Матрица содержит равномерное распределение чисел от 0 до 1:

array([[0.26818562, 0.65506793, 0.50035001],
[0.527117 , 0.445688 , 0.99661 ]])

Точно так же, чтобы создать матрицу случайных чисел с распределением
Гаусса (или
«нормальным» распределением), вы можете вместо этого использовать
randn как показано ниже:

random = np.random.randn(2, 3)

Наконец, для создания массива случайных целых чисел в randint
существует метод randint. Метод randint принимает нижнюю границу,
верхнюю границу и количество возвращаемых целых чисел. Например, если вы
хотите создать массив из 5 случайных целых чисел от 50 до 100, вы можете
использовать этот метод следующим образом:

random = np.random.randint(50, 100, 5)

В нашем случае результат выглядел так:

array([54, 59, 84, 62, 74])

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

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

Изменение формы массива NumPy

Используя NumPy, вы можете преобразовать одномерный массив в двумерный
массив, используя метод reshape

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

nums = np.arange(1, 17)

nums представляет собой одномерный массив из 16 элементов в диапазоне
от 1 до 16:

array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])

Нет, давайте преобразуем его в двумерный массив из 4 строк и 4 столбцов:

nums2 = nums.reshape(4, 4)

Теперь массив выглядит так:

array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])

Уместно упомянуть, что вы не можете изменить форму массива, если
количество элементов в одномерном массиве не равно произведению строк и
столбцов измененного массива. Например, если у вас 45 элементов в
одномерном массиве, вы не можете преобразовать его в матрицу из 5 строк
и 10 столбцов, поскольку матрица 5×10 имеет 50 элементов, а исходная —
только 45.

Поиск максимальных / минимальных значений

Вы можете использовать функции min / max чтобы легко найти значение
наименьшего и наибольшего числа в вашем массиве. В нашем примере давайте
сначала создадим массив из 5 случайных целых чисел:

random = np.random.randint(1, 100, 5)
print(random)

Наш массив случайных целых чисел выглядит так:

[51 40 84 38 1]

Помните, что эти числа генерируются случайным образом, поэтому у вас,
скорее всего, будет другой набор чисел. Давайте воспользуемся min и
max чтобы найти минимальное и максимальное значения из только что
созданного массива. Для этого выполните следующий код, чтобы найти
минимальное значение:

xmin = random.min()
print(xmin)

На выходе будет напечатано «1».

Точно так же для максимального значения выполните следующий код:

xmax = random.max()
print(xmax)

Приведенный выше сценарий вернет в качестве вывода «84».

Вы также можете найти индекс максимального и минимального значений,
используя функции argmax() и argmin() . Взгляните на следующий
сценарий:

print(random.argmax())

Приведенный выше сценарий напечатает «2», поскольку 84 — это наибольшее
число в списке, и оно находится во второй позиции массива.

Точно так же argmin() вернет «4», потому что 1 — наименьшее число и
находится в 4-й позиции.

Индексирование массивов в NumPy

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

Индексирование с помощью одномерных массивов

Создадим простой массив из 15 чисел:

nums = np.arange(1, 16)

Вы можете получить любой элемент, передав номер индекса. Как и списки
Python, массивы NumPy имеют нулевой индекс. Например, чтобы найти
элемент во втором индексе (3-й позиции) массива, вы можете использовать
следующий синтаксис:

print(nums[2])

У нас есть цифра 3 во втором индексе, поэтому она будет напечатана на
экране.

Вы также можете распечатать диапазон чисел с помощью индексации. Чтобы
получить диапазон, вам необходимо передать начальный индекс и индекс на
единицу меньше конечного, разделенные двоеточием, внутри квадратных
скобок, следующих за именем массива. Например, чтобы получить элементы с
первого по седьмой индекс, вы можете использовать следующий синтаксис:

print(nums[1:8])

Приведенный выше скрипт напечатает целые числа от 2 до 8:

[2 3 4 5 6 7 8]

Здесь, в nums , у нас есть 2 в индексе 1 и 8 в индексе семь.

Вы также можете нарезать массив и назначить элементы нарезанного массива
новому массиву:

nums2 = nums[0:8]
print(nums2)

В приведенном выше сценарии мы разрезали nums , извлекая его первые 8
элементов. Результирующие элементы присваиваются массиву nums2 Затем
мы nums2 массив nums2 на консоль. На выходе получается новый массив из
первых 8 чисел:

[1 2 3 4 5 6 7 8]

Индексирование с помощью двумерных массивов

Индексирование двумерного массива NumPy очень похоже на индексирование
матрицы. Давайте сначала создадим двумерный массив NumPy 3×3. Для этого
запустите следующий код:

nums2d = np.array(([1,2,3],[4,5,6],[7,8,9]))

Теперь распечатаем:

print(nums2d)

[[1 2 3]
[4 5 6]
[7 8 9]]

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

nums2d элемент из массива nums2d, расположенный в первой строке и
первом столбце:

print(nums2d[0, 0])

На выходе вы увидите «1». Точно так же мы можем получить элемент в
третьей строке и третьем столбце следующим образом:

print(nums2d[2, 2])

На выходе вы увидите цифру «9».

Помимо извлечения одного элемента, вы можете извлечь всю строку, передав
в квадратные скобки только индекс строки. Например, следующий скрипт
возвращает первую строку из массива nums2d

print(nums2d[0])

На выходе получается одномерный массив:

[1 2 3]

Аналогично, чтобы получить только первый столбец, вы можете использовать
следующий синтаксис:

print(nums2d[:,0])

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

[1 4 7]

Наконец, чтобы получить элементы из первых двух строк и первых двух
столбцов, можно использовать следующий синтаксис:

print(nums2d[:2,:2])

Приведенный выше сценарий возвращает следующий результат:

[[1 2]
[4 5]]

Арифметические операции с массивами NumPy

Для примеров в этом разделе мы будем использовать nums который мы
создали в последнем разделе.

Давайте сначала сложим два массива:

nums3 = nums + nums

Вы можете добавить два массива с одинаковыми размерами. Например, nums
содержит 15 элементов, поэтому мы можем добавить его к себе. Будут
добавлены элементы с соответствующими индексами. Теперь, если вы
распечатаете nums3 , результат будет выглядеть так:

[ 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30]

Как видите, каждая позиция — это сумма двух элементов в этой позиции в
исходных массивах.

Если вы добавите массив со скалярным значением, значение будет добавлено
к каждому элементу в массиве. Добавим 10 в nums и выведем полученный
массив на консоль. Вот как бы вы это сделали:

nums3 = nums + 10
print(nums3)

И результирующий nums3 становится:

[11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]

Таким же образом можно выполнять вычитание, сложение, умножение и
деление.

Помимо простой арифметики, вы можете выполнять более сложные функции с
массивами Numpy, например, журнал, квадратный корень, экспоненциальный и
т. Д.

Функция журнала

Следующий код просто возвращает массив с журналом всех элементов
входного массива:

nums3 = np.log(nums)
print(nums3)

Результат выглядит так:

[0. 0.69314718 1.09861229 1.38629436 1.60943791 1.79175947
1.94591015 2.07944154 2.19722458 2.30258509 2.39789527 2.48490665
2.56494936 2.63905733 2.7080502 ]

Функция exp

Следующий скрипт возвращает массив с показателями всех элементов
входного массива:

nums3 = np.exp(nums)
print(nums3)

[2.71828183e+00 7.38905610e+00 2.00855369e+01 5.45981500e+01
1.48413159e+02 4.03428793e+02 1.09663316e+03 2.98095799e+03
8.10308393e+03 2.20264658e+04 5.98741417e+04 1.62754791e+05
4.42413392e+05 1.20260428e+06 3.26901737e+06]

Функция sqrt

Следующий скрипт возвращает массив с квадратными корнями всех элементов
входного массива:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *