NumPy — это библиотека Python, широко используемая в науке о данных, поскольку она позволяет эффективно работать с большими объемами данных.

Что делает эту библиотеку настолько эффективной, так это то, что она частично написана на Python и в основном на C/C++.

Начиная

Первое, что нужно сделать, это установить NumPy. Вы можете сделать это легко с помощью pip :

pip install numpy

Затем вы можете импортировать NumPy следующим образом:

import numpy as np

Импортировать NumPy под псевдонимом np — это стандарт, так делают большинство разработчиков, так что вам тоже следует.

Теперь вы можете создать первый массив и распечатать его:

array = np.array([1, 2, 3, 4, 5])
print(array)
print(type(array))

# [1 2 3 4 5]
# <class 'numpy.ndarray'>

Многомерные массивы

Нет ограничений на количество измерений ваших массивов. Начнем с массива 0-D:

zero_dim_array = np.array(1)
print(zero_dim_array)

# 1

Массив 0-D — это просто число. Теперь, если мы создадим массив нулевых массивов, у нас будет одномерный массив:

one_dim_array = np.array([1, 2, 3, 4, 5])
print(one_dim_array)

# [1 2 3 4 5]

Если мы создадим массив одномерных массивов, у нас будет двумерный массив:

two_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
print(two_dim_array)

""" 
[[1 2 3]
[4 5 6]]
"""

Максимальное количество измерений — 32, но я думаю, вы никогда не будете использовать такие большие массивы. Давайте создадим еще несколько массивов:

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

four_dim_array = np.array([[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]], [[[13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24]]]])
print(four_dim_array)

"""
[[[ 1  2  3]
  [ 4  5  6]]

 [[ 7  8  9]
  [10 11 12]]]
"""

"""
[[[[ 1  2  3]
   [ 4  5  6]]

  [[ 7  8  9]
   [10 11 12]]]


 [[[13 14 15]
   [16 17 18]]

  [[19 20 21]
   [22 23 24]]]]
"""

Вы также можете использовать ndmin для создания массива с определенным номером измерения:

five_dim_array = np.array([0], ndmin=5)
print(five_dim_array)

# [[[[[0]]]]]

Чтобы проверить количество измерений в массиве, вы можете использовать array.ndim .

print(five_dim_array.ndim)

# 5

Форма

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

Мы получаем доступ к нему, используя array.shape

print(four_dim_array.shape)

for i in range(four_dim_array.ndim):
    print(f"Dimension {i}: {four_dim_array.shape[i]}")

# (2, 2, 2, 3)
# Dimension 0: 2
# Dimension 1: 2
# Dimension 2: 2
# Dimension 3: 3

Мы можем изменить форму массивов, используя array.reshape(new_shape) . Новая форма должна быть совместима с массивом. Чтобы объяснить этот принцип совместимости, давайте возьмем пример.

Представьте себе массив такой формы: (3, 3) . 1-е измерение содержит 3 элемента, а 2-е измерение содержит 3 элемента. Это означает, что массив содержит 9 значений, потому что вы можете сделать 3 строки массивов из 3 значений.

При форме (2, 3, 3, 1, 5) массив содержит 2*3*3*1*5 = 90 значений. Если мы хотим изменить его форму, другая форма должна содержать также 90 значений. Таким образом, возможная форма будет (10, 3, 3) . Давайте попробуем это:

array1 = np.array([1, 2], [3, 4], [5, 6])
print(array1.size)
print(array1.shape)

# 6
# (3, 2)

Размер массива равен 6, поэтому другие формы могут быть (2, 3), (1, 6) или (1, 1, 1, 1, 6).

    new_array1 = array1.reshape(2, 3)
    new_array2 = array1.reshape(1, 6)
    new_array3 = array1.reshape(1, 1, 1, 1, 6)

    print(new_array1)
    print(new_array2)
    print(new_array3)

Этот код работает! Если вы измените форму на что-то, что не может содержать 6 значений, это вызовет исключение.

Индексация

Доступ к массивам NumPy можно получить так же, как и к многомерным спискам. Есть и другой способ. Давайте проверим этот пример:

    two_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
    print(two_dim_array[0])
    print(two_dim_array[0][1])
    print(two_dim_array[0, 1])
    
    # [1 2 3]
    # 2
    # 2

Вы также можете использовать отрицательное индексирование:

    print(two_dim_array[-1][1])
    
    # 5

Зная, как работает индексация, теперь мы можем создавать слайсы:

    print(two_dim_array[0][1:3])
    print(two_dim_array[0, 1:3])
    print(two_dim_array[0, 1:])
    print(two_dim_array[-1, ::-1])

    # [2 3]
    # [2 3]
    # [2 3]
    # [6 5 4]

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

Итерация

Итерация также работает так же, как и для списков. Начнем с простейшего примера, одномерного массива:

    one_dim_array = np.array([1, 2, 3, 4, 5])
    for x in one_dim_array:
        print(x, end=" ")

    # 1 2 3 4 5

Здесь нет проблем, это то же самое, что и этот код:

    one_dim_list = [1, 2, 3, 4, 5]
    for x in one_dim_list:
        print(x, end=" ")

При работе с двумерными массивами все становится немного сложнее, но все же логично:

    two_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
    for x in two_dim_array:
        print(x, end=" ")

    # [1 2 3] [4 5 6]

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

    for x in two_dim_array:
        for y in x:
            print(y, end=" ")
            
    # 1 2 3 4 5 6

Or:

    for x in two_dim_array.flat:
        print(x, end=" ")
        
    # 1 2 3 4 5 6

flat используется для получения сглаженного массива. Мы также можем использовать array.flatten() для создания одномерного массива из n-D массива.

    flat_array = two_dim_array.flatten()
    print(flat_array)
    print(flat_array.ndim)
    print(flat_array.shape)
    
    # [1 2 3 4 5 6]
    # 1
    # (6,)

Другой способ перебрать все скалярные элементы — использовать nditer :

    for x in np.nditer(two_dim_array):
        print(x, end=" ")

    # 1 2 3 4 5 6

Благодаря этому мы можем перебирать сложные массивы n-D со многими измерениями!

    six_dim_array = np.array([[[[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]], [[[13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24]]]]]])
    for x in np.nditer(six_dim_array):
        print(x, end=" ")
        
    # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Заключительное примечание

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

Кстати, вы можете задаться вопросом, как можно использовать такие массивы. Есть много приложений. Например, игровое поле. Вместо использования многомерных списков Python вы можете использовать массивы NumPy.

Вы можете попробовать закодировать игру Tic Tac Toe, используя NumPy. Вот — решение, но обязательно попробуйте его перед проверкой!

Чтобы узнать больше о моих историях о Python, нажмите здесь! Вы также можете получить доступ ко всему моему контенту, проверив эту страницу.

Если вам понравилась история, не забудьте похлопать, прокомментировать и, возможно, подписаться на меня, если вы хотите узнать больше о моем содержании :)

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

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