🐍 Самоучитель по Python для начинающих. Часть 24: Основы работы с NumPy

Покажем основные методы обработки многомерных массивов и научим делать простые фильтры для изображений. В конце статьи – 10 инженерных и экономических задач с решениями.
🐍 Самоучитель по Python для начинающих. Часть 24: Основы работы с NumPy

NumPy – одна из самых популярных библиотек для инженерных и научных вычислений в Python: она содержит множество методов для работы с многомерными массивами и матрицами и отличается высокой скоростью обработки больших объемов данных. Мощная функциональность NumPy используется в нескольких других популярных библиотеках – Pandas, SciPy, Matplotlib, Scikit-learn и TensorFlow.

Основные сферы применения

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

  • Инженерные и научные вычисления в области физики, математики, биологии, химии и т.д.
  • Обработка изображений и звука – изменение размера, применение фильтров, сжатие и т.п.
  • Машинное обучение, искусственный интеллект и Data Science – обработка и статистический анализ данных.
  • Компьютерное зрение – распознавание образов и сегментация изображений.
  • Финансовые вычисления – расчет доходности активов и инвестиций, риск-менеджмент, оценка дисконтированной стоимости и т.д.
  • Геофизические и геологические исследования – обработка геоданных и анализ графиков.

Массив ndarray

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

Массивы NumPy используют меньше памяти и работают быстрее, чем обычные списки Python: инструменты библиотеки, для которых критична скорость, реализованы на C/C++. Кроме того, NumPy использует собственный тип данных, который называется ndarray (n-размерным массивом). Сравним быстродействие обычного Python кода и метода NumPy на примере сложения двух матриц 1000 х 1000:

        import numpy as np
import time

# Определяем две матрицы размером 1000x1000 со случайными целыми числами от 0 до 9
A = np.random.randint(0, 10, size=(1000, 1000))
B = np.random.randint(0, 10, size=(1000, 1000))

# Сложение матриц средствами Python
start_time = time.time()
C = [[A[i][j] + B[i][j] for j in range(len(A[0]))] for i in range(len(A))]
end_time = time.time()

# Сложение матриц с помощью NumPy
start_time_np = time.time()
D = A + B
end_time_np = time.time()

# Выводим результаты и время выполнения
print(f"Время выполнения Python сложения: {end_time - start_time} сек")
print(f"Время выполнения NumPy сложения: {end_time_np - start_time_np} сек")

# Сравниваем результаты
print("Результаты совпадают:", np.array_equal(C, D))
    

Результат:

        Время выполнения Python сложения: 1.432081937789917 сек
Время выполнения NumPy сложения: 0.004000186920166016 сек
Результаты совпадают: True
    

Ключевые особенности ndarray:

  • Однородность. Все элементы массива относятся к одному типу данных. Это позволяет сделать все операции с ndarray быстрыми и экономичными.
  • Многомерность. Массивы NumPy могут иметь любое количество измерений. С помощью одномерного массива можно представить список значений, двумерного – таблицу, трехмерного – изображение, четырехмерного – видео.
  • Фиксированная размерность. Размерность массива нельзя изменить после его создания. Если нужен массив другой размерности, необходимо создать новый.
  • Эффективность. Массивы NumPy поддерживают проведение множества операций над всеми элементами одновременно, что делает их более эффективными, чем обычные списки Python.
  • Удобные методы. NumPy предоставляет обширный выбор методов для всевозможных манипуляций над массивами – от сортировки и фильтрации до изменения формы.
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»

Как создать массив в NumPy

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

        import numpy as np

# Создание массива из списка
a = np.array([1, 2, 3, 4, 5])
print(a)

# Создание двумерного массива из списка списков
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(b)

# Создание массива из диапазона значений
c = np.arange(0, 10, 2)  # Создаем массив из значений от 0 до 10 с шагом 2
print(c)

# Создание массива из равномерно распределенных значений
d = np.linspace(0, 1, 5)  # Создаем массив из 5 равномерно распределенных значений от 0 до 1
print(d)

# Создание массива из случайных значений
e = np.random.rand(3, 3)  # Создаем массив из 3x3 случайных значений
print(e)

# Создание массива из нулей
f = np.zeros((2, 3))  # Создаем массив из нулей размером 2x3
print(f)

# Создание массива из единиц
g = np.ones((3, 3))   # Создаем массив из единиц размером 3x3
print(g)

    

Результат:

        [1 2 3 4 5]
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[0 2 4 6 8]
[0.   0.25 0.5  0.75 1.  ]
[[0.66777626 0.88439902 0.22572609]
 [0.09556062 0.40293789 0.58901436]
 [0.33380993 0.20922535 0.42657995]]
[[0. 0. 0.]
 [0. 0. 0.]]
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

    

Основные операции с массивами

Продемонстрируем базовые операции на примере двумерного массива:

        import numpy as np

# Создаем двумерный массив
arr = np.array([[1, 2], [3, 4], [5, 6]])

# Выводим массив на экран
print(arr)

# Получаем размерность массива
print(arr.shape)

# Получаем элементы массива
print(arr[0, 1])   # Выведет 2
print(arr[2, 0])   # Выведет 5

# Изменяем элементы массива
arr[0, 1] = 7
arr[1, 1] = 8
arr[2, 1] = 9
print(arr)

# Выводим строку
print(arr[1])   # Выведет [3 8]

# Выводим столбец
print(arr[:, 0])   # Выведет [1 3 5]

# Выводим срез
print(arr[:2, 1])   # Выведет [7 8]

    

Результат:

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

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

        import numpy as np

# Создаем два массива размером 6x6 со случайными целыми числами от 0 до 9
a = np.random.randint(1, 10, size=(6, 6))
b = np.random.randint(1, 10, size=(6, 6))

# Выводим массивы на экран
print("Массив a:\n", a)
print("Массив b:\n", b)

# Вычитаем массивы
d = a - b
print("Разность массивов a и b:\n", d)


# Умножение массивов
m = np.dot(a, b)
print("Произведение массивов a и b:\n", m)

# Деление массивов (умножение на обратную матрицу)
# Вычисляем обратную матрицу b
b_inv = np.linalg.inv(b)

# Умножаем матрицу a на обратную матрицу b_inv
result = np.dot(a, b_inv)
print("Результат деления массива a на b:\n", result)

# Транспонируем массивы
h = np.transpose(a)
i = np.transpose(b)
print("Массив a после транспонирования:\n", h)
print("Массив b после транспонирования:\n", i)

# Получаем статистические параметры массивов
std_a = np.std(a)            # Стандартное отклонение массива a
median_b = np.median(b)      # Медиана массива b
variance_a = np.var(a)       # Дисперсия массива a
min_b = np.min(b)            # Минимальное значение массива b
max_a = np.max(a)            # Максимальное значение массива a
sum_b = np.sum(b)            # Сумма элементов массива b
product_a = np.product(a, dtype=np.uint64)    # Произведение элементов массива a
prod_b = np.prod(b, dtype=np.uint64)          # Еще один метод вычисления произведения элементов
print("Стандартное отклонение массива a:", std_a)
print("Медиана массива b:", median_b)
print("Дисперсия массива a:", variance_a)
print("Минимальное значение массива b:", min_b)
print("Максимальное значение массива a:", max_a)
print("Сумма элементов массива b:", sum_b)
print("Произведение элементов массива a:", product_a)
print("Произведение элементов массива b:", prod_b)

    

Результат:

        Массив a:
 [[2 2 3 9 8 2]
 [4 7 6 6 1 5]
 [6 8 5 7 6 7]
 [5 3 2 6 5 5]
 [8 5 3 7 3 3]
 [5 8 2 6 1 1]]
Массив b:
 [[4 1 6 4 9 4]
 [6 8 2 2 3 4]
 [2 4 9 9 7 6]
 [9 4 2 9 2 3]
 [5 8 4 7 9 8]
 [2 7 4 6 9 9]]
Разность массивов a и b:
 [[-2  1 -3  5 -1 -2]
 [-2 -1  4  4 -2  1]
 [ 4  4 -4 -2 -1  1]
 [-4 -1  0 -3  3  2]
 [ 3 -3 -1  0 -6 -5]
 [ 3  1 -2  0 -8 -8]]
Произведение массивов a и b:
 [[151 144 101 188 153 143]
 [139 151 128 175 165 151]
 [189 215 163 232 244 218]
 [131 136 106 163 170 147]
 [152 133 123 171 176 142]
 [133 116  84 121 113  99]]
Результат деления массива a на b:
 [[-5.55598908e-01 -1.94654702e+00  4.39719079e-01 -6.62504877e-01
   5.72922357e+00 -3.83066719e+00]
 [-2.90479906e-01  1.16172454e+00  8.37690207e-01  3.86071011e-01
  -1.83749512e+00  1.11451424e+00]
 [ 4.77955521e-03  6.06808428e-01  2.70971518e-01  2.91162700e-01
  -3.96898166e-01  5.81057355e-01]
 [ 3.19791260e-01 -5.26238783e-02 -2.67752634e-01  6.75039017e-01
  -7.08788529e-01  1.02033750e+00]
 [ 5.16972298e-02  2.57315646e-01  1.34998049e-01  5.37065938e-01
   4.00897386e-01 -4.29379633e-01]
 [-1.07915529e+00 -1.51531409e-01  7.47073742e-01 -5.26092470e-01
   3.97107881e+00 -3.19444986e+00]]
Массив a после транспонирования:
 [[2 4 6 5 8 5]
 [2 7 8 3 5 8]
 [3 6 5 2 3 2]
 [9 6 7 6 7 6]
 [8 1 6 5 3 1]
 [2 5 7 5 3 1]]
Массив b после транспонирования:
 [[4 6 2 9 5 2]
 [1 8 4 4 8 7]
 [6 2 9 2 4 4]
 [4 2 9 9 7 6]
 [9 3 7 2 9 9]
 [4 4 6 3 8 9]]
Стандартное отклонение массива a: 2.27438772116208
Медиана массива b: 5.5
Дисперсия массива a: 5.172839506172839
Минимальное значение массива b: 1
Максимальное значение массива a: 9
Сумма элементов массива b: 197
Произведение элементов массива a: 18210394348833472512
Произведение элементов массива b: 14758432146536267776
    

Полезные методы NumPy

reshape() – меняет форму массива без изменения данных:

        import numpy as np

# создаем массив размером 3x4
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

# используем метод reshape() для изменения формы массива на 2x6
new_arr = arr.reshape(2, 6)

print("Исходный массив:")
print(arr)
print("Массив после изменения формы:")
print(new_arr)

    

Результат:

        Исходный массив:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
Массив после изменения формы:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]
    

concatenate() – объединяет массивы по строкам или по столбцам:

        import numpy as np

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

#объединяем массивы по горизонтальной оси (по строкам)
d = np.concatenate((a, b, c), axis=1) 
print(d)
#объединяем массивы по вертикальной оси (по столбцам)
e = np.concatenate((a, b, c), axis=0)
print(e)

    

Результат:

        [[ 1  2  5  6  9 10]
 [ 3  4  7  8 11 12]]
[[ 1  2]
 [ 3  4]
 [ 5  6]
 [ 7  8]
 [ 9 10]
 [11 12]]

    

flatten() – превращает многомерный массив в одномерный:

        import numpy as np
a = np.array([[1, 2, 9, 8], [7, 5, 3, 4], [2, 1, 5, 6], [4, 8, 7, 8]])
print(a.flatten())

    

Результат;

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

argmax() и argmin() – возвращают индексы максимального (минимального) элемента массива:

        import numpy as np

a = np.array([[4, 2, 9, 89], [17, 5, 3, 14], [25, -5, 5, 6], [4, 18, 17, 8]])
print(f"Индекс максимального элемента: {np.argmax(a)}")
print(f"Индекс минимального элемента: {np.argmin(a)}")

    

Результат:

        Индекс максимального элемента: 3
Индекс минимального элемента: 9

    

where() – выбирает из массива элементы, удовлетворяющие определенному условию:

        import numpy as np

arr = np.array([[14, 22, 91, 19], [11, 51, 32, 14], [25, 22, 50, 60], [14, 18, 17, 28]])
# формируем новый массив из четных элементов исходного, заменяя нечетные на цифру 5
new_arr = np.where(arr % 2 == 0, arr, 5)
print(new_arr)

    

Результат:

        [[14 22  5  5]
 [ 5  5 32 14]
 [ 5 22 50 60]
 [14 18  5 28]]

    

В NumPy есть еще один метод, похожий на where()argwhere(). Он возвращает индексы элементов, соответствующих условию, в виде массива:

        import numpy as np

# Создание двумерного массива
arr = np.random.randint(0, 5, size=(5, 5))
print("Массив:")
print(arr)
result = np.argwhere(arr != 3)
print(result)

    

Результат:

        Массив:
[[4 3 0 1 1]
 [0 0 0 4 1]
 [1 1 2 0 0]
 [3 0 0 3 1]
 [2 2 4 3 0]]
[[0 0]
 [0 2]
 [0 3]
 [0 4]
 [1 0]
 [1 1]
 [1 2]
 [1 3]
 [1 4]
 [2 0]
 [2 1]
 [2 2]
 [2 3]
 [2 4]
 [3 1]
 [3 2]
 [3 4]
 [4 0]
 [4 1]
 [4 2]
 [4 4]]

    

nonzero() – возвращает индексы ненулевых элементов:

        import numpy as np

# Создание двумерного массива
arr = np.random.randint(0, 2, size=(5, 5))
print("Массив:")
print(arr)
result = np.nonzero(arr)
print(result)

    

Результат:

        Массив:
[[0 1 0 0 0]
 [1 1 0 1 0]
 [1 0 1 0 1]
 [1 0 1 1 0]
 [0 1 0 1 0]]
(array([0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4], dtype=int32), array([1, 0, 1, 3, 0, 2, 4, 0, 2, 3, 1, 3], dtype=int32))

    

unique() – возвращает уникальные элементы:

        import numpy as np

# создание массива случайных чисел размером 500x500
arr = np.random.randint(low=0, high=10, size=(500, 500))

# вывод уникальных значений массива
unique_values, counts = np.unique(arr, return_counts=True)
print(arr)
print(unique_values)
print(f"Количество вхождений каждого уникального числа: {counts}")

    

Результат:

        [[1 8 1 ... 6 3 0]
 [4 5 5 ... 6 4 9]
 [3 1 4 ... 2 5 8]
 ...
 [3 5 3 ... 0 7 7]
 [0 4 0 ... 8 5 4]
 [6 3 5 ... 0 2 2]]
[0 1 2 3 4 5 6 7 8 9]
Количество вхождений каждого уникального числа: [25119 25042 25089 25186 24868 24888 24926 24941 24854 25087]

    

sort() – сортирует массив по возрастанию / убыванию:

        import numpy as np

arr = np.array([3, 12, 4, 1, 5, 9, 2, 6, 15, -4, 10, -2, 0, 11, 7])
# сортировка по возрастанию
sorted_asc = np.sort(arr)
# сортировка по убыванию
sorted_des = np.sort(arr)[::-1]
print(sorted_asc)
print(sorted_des)

    

Результат:

        [-4 -2  0  1  2  3  4  5  6  7  9 10 11 12 15]
[15 12 11 10  9  7  6  5  4  3  2  1  0 -2 -4]

    

diag() – возвращает диагональ матрицы. Также метод можно использовать для создания диагональной матрицы из заданных элементов:

        import numpy as np

# Создание двумерного массива
arr = np.arange(16).reshape((4, 4))
print("Исходный массив:")
print(arr)

# Получение значения главной диагонали
print("\nГлавная диагональ массива:")
print(np.diag(arr))

# Создание диагональной матрицы из указанных элементов
diag_matrix = np.diag([1, 2, 3, 4, 5])
print("\nДиагональная матрица:")
print(diag_matrix)

    

Результат:

        Исходный массив:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]

Главная диагональ массива:
[ 0  5 10 15]

Диагональная матрица:
[[1 0 0 0 0]
 [0 2 0 0 0]
 [0 0 3 0 0]
 [0 0 0 4 0]
 [0 0 0 0 5]]

    

trace() вычисляет след матрицы, то есть сумму элементов на ее главной диагонали:

        import numpy as np

# Создание двумерного массива
arr = np.random.randint(0, 10, size=(20, 20))
print("Исходный массив:")
print(arr)
# Вычисление следа матрицы
trace = np.trace(arr)
print("След матрицы:")
print(trace)

    

Результат:

        Исходный массив:
[[0 2 9 3 8 9 6 5 4 8 2 1 9 6 0 5 9 1 4 8]
 [8 1 3 1 5 8 9 4 6 7 7 3 6 5 7 3 4 6 4 7]
 [4 4 9 2 8 3 1 0 9 1 7 6 6 3 5 5 3 8 5 2]
 [7 9 5 9 5 5 5 4 2 2 8 5 8 8 8 1 6 9 9 0]
 [5 3 8 2 3 2 6 7 8 5 2 9 7 4 7 8 3 2 8 0]
 [7 1 4 8 7 0 5 6 1 5 7 2 1 5 3 7 9 3 0 1]
 [9 9 1 5 3 2 9 5 4 3 2 1 9 5 5 3 5 1 0 7]
 [3 8 6 0 7 0 8 8 8 7 4 6 7 3 8 0 0 7 5 8]
 [3 5 5 7 6 1 0 6 3 8 0 9 7 1 3 4 1 8 3 4]
 [1 9 4 3 6 3 2 4 6 2 4 3 8 5 8 5 4 5 4 8]
 [5 4 2 0 9 8 1 3 8 0 9 1 6 9 4 2 0 8 3 4]
 [6 4 1 4 9 8 6 0 7 7 0 1 9 3 5 3 8 7 9 2]
 [9 4 9 2 5 2 8 6 0 9 0 6 4 1 7 0 6 4 2 8]
 [2 6 7 2 5 1 7 0 9 9 4 8 2 1 8 6 8 9 3 0]
 [1 8 3 8 2 6 3 0 0 0 4 0 1 4 2 4 3 2 8 9]
 [3 9 2 6 6 7 8 4 3 6 6 0 1 6 2 8 8 6 8 7]
 [6 2 1 3 0 1 6 5 7 6 8 6 4 5 3 9 3 1 3 2]
 [6 2 9 4 4 8 1 3 1 8 1 2 4 9 8 2 3 9 7 8]
 [1 2 8 7 4 6 9 5 4 9 3 9 2 8 3 8 1 8 2 3]
 [9 8 6 2 5 9 9 6 3 0 6 5 6 5 7 7 7 9 4 7]]
След матрицы:
90

    

Интересные возможности NumPy

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

Эффективное хранение и быстрая загрузка данных

NumPy поддерживает загрузку данных из файлов различных форматов. Так, например, можно сохранить массив и загрузить его из текстового файла (txt, csv, json):

        import numpy as np

data = np.array([[1, 2, 3], [4, 5, 6]])
np.savetxt("data.txt", data, delimiter=",")
data = np.loadtxt("data.txt", delimiter=",", dtype=np.int32)
print(data)

    

Однако при работе с очень большими объемами информации стоит использовать собственные бинарные форматы NumPynpy и npz: они экономят до 50% места на диске и загружаются быстрее, чем любые текстовые файлы.

Так сохраняют и загружают npy файлы:

        import numpy as np

data = np.array([[1, 2, 3], [4, 5, 6]])
np.save("data.npy", data)
loaded_data = np.load("data.npy")
print(loaded_data)

    

Обработка изображений

С помощью NumPy изображения можно представить в виде трехмерных массивов, где каждый пиксель является результатом смешивания красного, зеленого и синего цветов (RGB). А четырехмерные массивы можно использовать для работы с изображениями с альфа-каналом (RGBA). Возьмем любое цветное изображение:

🐍 Самоучитель по Python для начинающих. Часть 24: Основы работы с NumPy

И обработаем его:

        import numpy as np
from PIL import Image

# загрузка изображения
img = np.array(Image.open('image.jpeg'))

# преобразование в черно-белое изображение
img_gray = np.mean(img, axis=2).astype(np.uint8)

# преобразование цветных каналов
img_R = img.copy()
img_R[:, :, (1, 2)] = 0
img_G = img.copy()
img_G[:, :, (0, 2)] = 0
img_B = img.copy()
img_B[:, :, (0, 1)] = 0

# объединение изображений
img_1 = Image.fromarray(img_gray)
img_2 = Image.fromarray(img_R)
img_3 = Image.fromarray(img_G)
img_4 = Image.fromarray(img_B)

result = Image.new("RGB", (img.shape[1]*2, img.shape[0]*2))
result.paste(img_1, (0,0))
result.paste(img_2, (img.shape[1],0))
result.paste(img_3, (0,img.shape[0]))
result.paste(img_4, (img.shape[1],img.shape[0]))

result.save("result.png", format="PNG")

    

Приведенный выше код загружает изображение в массив NumPy, после чего:

  • Преобразует его в черно-белое изображение при помощи функции np.mean().
  • Последовательно преобразует оригинальную картинку в изображения, которые содержат только красный, зеленый и синий цветовые каналы.
  • Создает четыре объекта Image.fromarray() из соответствующих массивов NumPy и объединяет их в одно изображение при помощи метода paste().

В итоге мы получаем разноцветный коллаж, где первая четверть – черно-белая, а остальные три – красная, зеленая и синяя:

🐍 Самоучитель по Python для начинающих. Часть 24: Основы работы с NumPy

Визуализация данных

NumPy (вместе с Matplotlib) отлично визуализирует большие объемы данных. На Yahoo Finance можно скачать исторические данные о стоимости любых акций и криптовалют. Скачаем, к примеру, csv файл с информацией о стоимости Litecoin за последние 5 лет. Код для визуализации цен закрытия будет выглядеть так:

        import numpy as np
import matplotlib.pyplot as plt

# Загрузка данных из файла
data = np.genfromtxt('litecoin.csv', delimiter=',', skip_header=1, usecols=(1, 2, 3, 4, 5, 6))

# Разделение данных на столбцы
open_prices, high_prices, low_prices, close_prices, adj_close_prices, volumes = data.T

# Создание графика цены закрытия
plt.plot(close_prices)

# Настройка осей
plt.xlabel('Месяцы')
plt.ylabel('Цена закрытия')
plt.title('Стоимость Litecoin за период с июля 2018 по июнь 2023')

# Установка значений на оси x
n = len(close_prices)
step = n // 10
plt.xticks(range(0, n, step))

# Отображение графика
plt.show()

    

Результат:

🐍 Самоучитель по Python для начинающих. Часть 24: Основы работы с NumPy

Практика

Задание 1

Напишите программу, которая:

  • Генерирует NumPy-массив 10х10, заполненный случайными числами от 1.01 до 9.99.
  • Выводит главную диагональ.
  • Выводит статистические данные о массиве – среднее значение, минимальный и максимальный элементы, медиану, дисперсию и стандартное отклонение.

Пример вывода:

        Массив: 
[[5.72 2.78 4.21 5.61 1.26 9.61 2.87 7.08 4.86 9.71]
 [6.37 4.92 8.99 4.77 2.5  4.91 3.64 5.54 6.35 1.04]
 [1.63 4.35 8.56 4.86 2.32 1.77 9.76 4.52 5.09 4.05]
 [2.55 3.3  6.57 7.27 4.08 2.77 6.53 5.04 4.69 2.99]
 [7.65 5.2  7.27 5.48 3.38 1.9  1.68 4.87 4.81 9.96]
 [3.65 5.97 2.92 2.13 3.58 6.24 4.53 9.06 3.64 4.35]
 [4.95 1.84 2.98 1.98 1.47 7.65 2.09 3.01 2.2  2.71]
 [9.44 3.26 6.6  6.44 6.45 5.9  2.36 3.96 7.21 9.18]
 [3.23 3.12 7.19 6.69 6.9  8.4  7.67 3.71 1.93 6.07]
 [6.48 2.57 5.52 5.8  2.32 7.07 9.22 2.43 4.43 4.05]]

Среднее значение: 4.90
Минимальный элемент: 1.04
Максимальный элемент: 9.96
Медиана: 4.79
Стандартное отклонение: 2.31
Дисперсия: 5.32

Диагональ: 
[5.72 4.92 8.56 7.27 3.38 6.24 2.09 3.96 1.93 4.05]

    

Решение:

        import numpy as np

# генерация массива 10 на 10 случайных чисел в интервале от 1.01 до 9.99
arr = np.random.uniform(low=1.01, high=9.99, size=(10,10))

# округление элементов массива до 2 знаков
arr = np.around(arr, decimals=2)

# вывод массива
print(f"Массив: \n{arr}")

# вывод статистической информации
print(f"\nСреднее значение: {arr.mean():.2f}")
print(f"Минимальный элемент: {np.min(arr):.2f}")
print(f"Максимальный элемент: {np.max(arr):.2f}")
print(f"Медиана: {np.median(arr):.2f}")
print(f"Стандартное отклонение: {np.std(arr):.2f}")
print(f"Дисперсия: {np.var(arr):.2f}")

# вывод диагонали массива
print(f"\nДиагональ: \n{np.diag(arr)}")

    

Задание 2

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

Пример вывода:

        Самый прибыльный сезон - лето
    

Решение:

        import numpy as np

# Данные о прокате велосипедов за каждый месяц сезона
spring_rentals = np.array([11362, 11489, 12842])
summer_rentals = np.array([15401, 16562, 17728])
autumn_rentals = np.array([14994, 13851, 12784])
winter_rentals = np.array([840, 950, 1210])

# Вычисление общего количества прокатов велосипедов для каждого сезона
total_spring_rentals = np.sum(spring_rentals)
total_summer_rentals = np.sum(summer_rentals)
total_autumn_rentals = np.sum(autumn_rentals)
total_winter_rentals = np.sum(winter_rentals)

# Вычисление среднего количества прокатов велосипедов для каждого сезона
average_spring_rentals = np.mean(spring_rentals)
average_summer_rentals = np.mean(summer_rentals)
average_autumn_rentals = np.mean(autumn_rentals)
average_winter_rentals = np.mean(winter_rentals)

# Создание массива средних значений
average_rentals = np.array([average_spring_rentals, average_summer_rentals, average_autumn_rentals, average_winter_rentals])

# Определение самого прибыльного сезона
most_profitable_season = np.argmax(average_rentals)

seasons = ['весна', 'лето', 'осень', 'зима']
print(f"Самый прибыльный сезон - {seasons[most_profitable_season]}")

    

Задание 3

Компания «ГрузАвто» производит грузовики на 4 заводах. Отчет о выполнении производственного плана по месяцам и заводам можно представить в виде массива:

        [
    # Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь
    [1000, 1200, 1500, 1350, 1400, 1300, 1250, 1450, 1300, 1550, 1600, 1700], # Завод 1
    [800, 900, 1000, 950, 1000, 1100, 1200, 1150, 1000, 1100, 1200, 1300], # Завод 2
    [1200, 1300, 1250, 1400, 1500, 1600, 1650, 1700, 1600, 1550, 1500, 1400], # Завод 3
    [900, 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450], # Завод 4
]

    

Напишите программу, которая определит:

  • Общее количество выпущенных грузовиков.
  • Количество грузовиков, произведенных на каждом заводе за год.
  • Самый продуктивный завод компании.

Пример вывода:

        Общее количество произведенных грузовиков за год: 61050
Завод 1 - 16600 грузовиков
Завод 2 - 12700 грузовиков
Завод 3 - 17650 грузовиков
Завод 4 - 14100 грузовиков
Завод 3 был самым продуктивным

    

Решение:

        import numpy as np

# Создание массива данных о производстве
production_data = np.array([
    # Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь
    [1000, 1200, 1500, 1350, 1400, 1300, 1250, 1450, 1300, 1550, 1600, 1700], # Завод 1
    [800, 900, 1000, 950, 1000, 1100, 1200, 1150, 1000, 1100, 1200, 1300], # Завод 2
    [1200, 1300, 1250, 1400, 1500, 1600, 1650, 1700, 1600, 1550, 1500, 1400], # Завод 3
    [900, 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450], # Завод 4
])

# Подсчет общего количества произведенных грузовиков за год
total_production = np.sum(production_data)

# Подсчет количества произведенных грузовиков на каждом заводе за год
total_production_by_factory = np.sum(production_data, axis=1)

# Определение завода, на котором было произведено больше всего грузовиков за год
most_productive_factory = np.argmax(total_production_by_factory) + 1

# Вывод общего количества произведенных грузовиков за год
print(f"Общее количество произведенных грузовиков за год: {total_production}")

# Вывод количества произведенных грузовиков на каждом заводе за год
for i, count in enumerate(total_production_by_factory):
    print(f"Завод {i+1} - {count} грузовиков")

# Вывод завода, на котором было произведено больше всего грузовиков за год
print(f"Завод {most_productive_factory} был самым продуктивным")

    

Задание 4

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

        production_plan = np.array([
    [110, 120, 80, 100, 200, 200, 100, 90, 150, 100, 205, 100],  
    [90, 110, 70, 110, 180, 200, 120, 80, 150, 100, 205, 110],    
    [80, 70, 90, 90, 150, 105, 105, 70, 90, 80, 105, 85],   
    [120, 140, 100, 120, 230, 100, 110, 80, 70, 90, 205, 110],  
    [130, 150, 110, 110, 240, 100, 110, 80, 75, 90, 205, 100],  
    [140, 160, 120, 110, 250, 100, 100, 80, 75, 90, 205, 120],  
    [150, 170, 130, 90, 260, 100, 100, 80, 80, 100, 205, 200],  
    [160, 180, 140, 120, 270, 100, 120, 80, 85, 100, 205, 210],  
    [170, 190, 150, 120, 280, 100, 130, 80, 90, 120, 205, 210],  
    [180, 200, 160, 130, 290, 100, 140, 80, 95, 130, 205, 220],  
    [190, 210, 170, 140, 300, 100, 130, 80, 150, 140, 205, 230],  
    [200, 220, 180, 150, 310, 100, 160, 80, 150, 200, 205, 250]   
])

prices_per_ton = np.array([10000, 150000, 12000, 80000, 2000, 33060, 5000, 10000, 170000, 19000, 8600, 7000])

    

Необходимо определить:

  • Месяцы с минимальными и максимальными затратами на сырье.
  • Виды продукции, на которые приходится минимальная и максимальная доли всех затрат.

Пример вывода:

        Больше всего затрат приходится на: Торт "Клубничный"
Меньше всего средств тратится на: Пряники "Изюм"
Месяц с минимальными затратами на сырье: март
Месяц с максимальными затратами на сырье: декабрь

    

Решение:

        import numpy as np

# Годовой план производства (в тоннах)
production_plan = np.array([
    [110, 120, 80, 100, 200, 200, 100, 90, 150, 100, 205, 100],  
    [90, 110, 70, 110, 180, 200, 120, 80, 150, 100, 205, 110],    
    [80, 70, 90, 90, 150, 105, 105, 70, 90, 80, 105, 85],   
    [120, 140, 100, 120, 230, 100, 110, 80, 70, 90, 205, 110],  
    [130, 150, 110, 110, 240, 100, 110, 80, 75, 90, 205, 100],  
    [140, 160, 120, 110, 250, 100, 100, 80, 75, 90, 205, 120],  
    [150, 170, 130, 90, 260, 100, 100, 80, 80, 100, 205, 200],  
    [160, 180, 140, 120, 270, 100, 120, 80, 85, 100, 205, 210],  
    [170, 190, 150, 120, 280, 100, 130, 80, 90, 120, 205, 210],  
    [180, 200, 160, 130, 290, 100, 140, 80, 95, 130, 205, 220],  
    [190, 210, 170, 140, 300, 100, 130, 80, 150, 140, 205, 230],  
    [200, 220, 180, 150, 310, 100, 160, 80, 150, 200, 205, 250]   
])

# Цены на сырье (за тонну)
prices_per_ton = np.array([10000, 150000, 12000, 80000, 2000, 33060, 5000, 10000, 170000, 19000, 8600, 7000])

# Вычисление объемов закупок сырья для каждого месяца и вида продукции
monthly_purchases = np.dot(production_plan, np.diag(prices_per_ton))

# Вычисление общей стоимости ежемесячных закупок сырья
total_costs = np.sum(monthly_purchases, axis=1)

months = ['январь', 'февраль', 'март', 'апрель', 'май', 'июнь',
          'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь']

# Виды продукции
products = np.array(['Печенье "Чебурашка"', 'Торт "Клубничный"', 'Конфеты "Птичка"', 'Шоколад "Золотой стандарт"', 'Пряники "Изюм"', 'Зефир "Бриз"', 'Пирожное "Тирамису"', 'Мармелад "Fruit&Berry"', 'Мусс "Крем-брюле"', 'Брауни "Ореховый"', 'Кекс "Праздник"', 'Батончики "Сюрприз"'])

# Названия ингредиентов
ingredients = np.array(['Мука', 'Сахар', 'Масло', 'Какао', 'Мед', 'Ваниль', 'Яйца', 'Кондитерская глазурь', 'Фрукты', 'Орехи', 'Кокосовая стружка', 'Сливки'])

# Суммарная стоимость по каждому виду продукции
product_costs = np.sum(monthly_purchases, axis=0)

# Виды продукции, на которые приходятся максимум и минимум затрат
most_expenses_index = np.argmax(product_costs)
least_expenses_index = np.argmin(product_costs)

# Индексы месяцев с минимальными и максимальными затратами на сырье
min_month_index = np.argmin(total_costs)
max_month_index = np.argmax(total_costs)

print(f"Больше всего затрат приходится на: {products[most_expenses_index]}")
print(f"Меньше всего средств тратится на: {products[least_expenses_index]}")

print(f"Месяц с минимальными затратами на сырье: {months[min_month_index]}")
print(f"Месяц с максимальными затратами на сырье: {months[max_month_index]}")

    

Задание 5

Напишите программу, которая будет определять, соответствует ли состав портфеля допустимому уровню риска.

Пример ввода:

        Прошлая доходность акций
10, 5, 15, 8, 12
Стандартное отклонение акций
2, 3, 4, 2.5, 3.5
Сумма
1000000
Допустимый уровень риска
10
Доли акций в портфеле
0.2, 0.3, 0.15, 0.25, 0.1

    

Вывод:

        Уровень риска портфеля соответствует требованиям.
    

Решение:

        import numpy as np

print("Прошлая доходность акций")
# Прошлая доходность акций (в процентах за период)
returns = np.array([float(element) for element in input().split(",")])

print("Стандартное отклонение акций")
# Стандартное отклонение акций (в процентах)
std_devs = np.array([float(element) for element in input().split(",")])

print("Сумма")
# Сумма, которой располагает инвестор
invest_amount = int(input())

print("Допустимый уровень риска")
# Допустимый уровень риска портфеля (в процентах)
risk_level = int(input())

# Вычисление взвешенной средней доходности портфеля
print("Доли акций в портфеле")
weights = np.array([float(element) for element in input().split(",")])
portfolio_returns = np.dot(returns, weights)

# Вычисление стандартного отклонения портфеля
portfolio_std_dev = np.sqrt(np.dot(weights, np.dot(std_devs, weights.T)))

# Проверка уровня риска портфеля
if (portfolio_std_dev <= risk_level).any():
    print("Уровень риска портфеля соответствует требованиям.")
else:
    print("Уровень риска слишком высок. Рекомендуем изменить веса акций в портфеле.")

    

Задание 6

Напишите программу, которая будет анализировать исторические данные о курсе биткоина с 01.01.22, выбирая из файла дни, когда:

  • Курс монеты превышал $ 30 000 в момент закрытия.
  • Объем торгов составлял не менее $ 16 000 000 000.

Пример вывода:

        2023-04-11 29653.679688 30509.083984 29609.300781 30235.058594 30235.058594 20121259843
2023-04-12 30231.582031 30462.480469 29725.574219 30139.052734 30139.052734 18651929926
2023-04-13 29892.740234 30539.845703 29878.623047 30399.066406 30399.066406 17487721001
2023-04-14 30409.562500 31005.607422 30044.498047 30485.699219 30485.699219 22659995079
2023-04-18 29449.091797 30470.302734 29154.849609 30397.552734 30397.552734 19480529496
2023-06-21 28311.310547 30737.330078 28283.410156 30027.296875 30027.296875 33346760979
2023-06-23 29896.382813 31389.539063 29845.214844 30695.468750 30695.468750 24115570085
2023-06-26 30480.523438 30636.029297 29955.744141 30271.130859 30271.130859 16493186997
2023-06-27 30274.320313 31006.787109 30236.650391 30688.164063 30688.164063 16428827944
2023-06-30 30446.085938 31238.339844 30363.273438 30821.589844 30821.589844 17436878848

    

Решение:

        import csv
import numpy as np

data = []
with open('BTC-USD.csv', 'r') as file:
    csv_reader = csv.reader(file)
    for row in csv_reader:
        data.append(row)

header = data[0]
close_prices_index = header.index('Close')
volumes_index = header.index('Volume')

close_prices = np.array([float(row[close_prices_index]) for row in data[1:]])
volumes = np.array([float(row[volumes_index]) for row in data[1:]])

threshold_price = 30000
threshold_volume = 16000000000

filtered_days = np.where((close_prices > threshold_price) & (volumes >= threshold_volume))

selected_days = [data[i+1] for i in filtered_days[0]]
for day in selected_days:
    print(*day)

    

Задание 7

Напишите кредитный калькулятор для вычисления переплаты при аннуитетном и дифференцированном способах погашения.

  • Сумма – 5 000 000 рублей.
  • Ставка – 12%.
  • Срок погашения – 3 года.

Пример вывода:

        Платеж    Аннуитетный    Дифференцированный
#1        166071.55      188888.89      
#2        166071.55      187500.0       
#3        166071.55      186111.11      
#4        166071.55      184722.22      
#5        166071.55      183333.33      
#6        166071.55      181944.44      
#7        166071.55      180555.56      
#8        166071.55      179166.67      
#9        166071.55      177777.78      
#10       166071.55      176388.89      
#11       166071.55      175000.0       
#12       166071.55      173611.11      
#13       166071.55      172222.22      
#14       166071.55      170833.33      
#15       166071.55      169444.44      
#16       166071.55      168055.56      
#17       166071.55      166666.67      
#18       166071.55      165277.78      
#19       166071.55      163888.89      
#20       166071.55      162500.0       
#21       166071.55      161111.11      
#22       166071.55      159722.22      
#23       166071.55      158333.33      
#24       166071.55      156944.44      
#25       166071.55      155555.56      
#26       166071.55      154166.67      
#27       166071.55      152777.78      
#28       166071.55      151388.89      
#29       166071.55      150000.0       
#30       166071.55      148611.11      
#31       166071.55      147222.22      
#32       166071.55      145833.33      
#33       166071.55      144444.44      
#34       166071.55      143055.56      
#35       166071.55      141666.67      
#36       166071.55      140277.78      

Переплата при аннуитетном погашении: 978575.77
Переплата при дифференцированном погашении: 925000.0

    

Решение:

        import numpy_financial as npf
import numpy as np

# Заданные параметры кредита
annual_interest_rate = 0.12
loan_amount = 5000000
loan_term = 3

# Расчет месячной процентной ставки и общего количества платежей
monthly_interest_rate = annual_interest_rate / 12
total_payments = loan_term * 12

# Расчет аннуитетного платежа
annuity_payment = npf.pmt(monthly_interest_rate, total_payments, -loan_amount)

# Расчет дифференцированного платежа
principal_payment = loan_amount / total_payments

# Расчет оставшейся суммы кредита для каждого месяца
remaining_loan_amounts = loan_amount - np.arange(total_payments) * principal_payment

# Расчет процентных платежей
interest_payments = remaining_loan_amounts * monthly_interest_rate

# Расчет дифференцированных платежей
differentiated_payments = principal_payment + interest_payments


# Вывод заголовка таблицы
print(f"{'Платеж':<10}{'Аннуитетный':<15}{'Дифференцированный':<15}")

# Вывод строк таблицы для каждого платежа
for i, payment in enumerate(differentiated_payments, 1):
    print(f"#{i:<9}{round(annuity_payment, 2):<15}{round(payment, 2):<15}")

# Расчет общих затрат на погашение кредита для аннуитетного и дифференцированного способов
total_cost_annuity = annuity_payment * total_payments
total_cost_differentiated = sum(differentiated_payments)

# Вывод общих затрат на погашение кредита
print(f"\nПереплата при аннуитетном погашении: {round(total_cost_annuity - loan_amount, 2)}")
print(f"Переплата при дифференцированном погашении: {round(total_cost_differentiated - loan_amount, 2)}")

    

Задание 8

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

  • Ускорение – 3.5, 4.2, 2.8, 3.5, 4.2, 5.1, 6.2, 3.9, 4.7
  • Сила – 250, 280, 220, 290, 310, 260, 265, 270, 275
  • Деформация – 0.02, 0.03, 0.01, 0.02, 0.03, 0.04, 0.05, 0.03, 0.02

Нужно:

  • Найти максимальные и минимальные значения ускорения, силы и деформации, а также время достижения этих показателей.
  • Вычислить площадь под кривыми ускорения и силы на протяжении всего временного ряда.
  • Рассчитать среднее значение и стандартное отклонение для ускорения и силы.

Пример вывода:

        Ускорение
Максимальное ускорение: 6.2
Время достижения максимального ускорения: 6
Минимальное ускорение: 2.8
Время достижения минимального ускорения: 2

Сила
Максимальная сила: 310
Время достижения максимальной силы: 4
Минимальная сила: 220
Время достижения минимальной силы: 2

Деформация
Максимальная деформация: 0.05
Время достижения максимальной деформации: 6
Минимальная деформация: 0.01
Время достижения минимальной деформации: 2

Интегральные параметры
Площадь под кривой ускорения: 34.0
Площадь под кривой силы: 2157.5

Статистика
Среднее значение ускорения: 4.23
Стандартное отклонение ускорения: 0.95
Среднее значение силы: 268.89
Стандартное отклонение силы: 23.90
    

Решение:

        import numpy as np

# Временные ряды
acceleration = np.array([3.5, 4.2, 2.8, 3.5, 4.2, 5.1, 6.2, 3.9, 4.7])
force = np.array([250, 280, 220, 290, 310, 260, 265, 270, 275])
deformation = np.array([0.02, 0.03, 0.01, 0.02, 0.03, 0.04, 0.05, 0.03, 0.02])

# Нахождение максимальных и минимальных значений и времени достижения для каждого параметра
max_acceleration = np.max(acceleration)
min_acceleration = np.min(acceleration)
time_of_max_acceleration = np.argmax(acceleration)
time_of_min_acceleration = np.argmin(acceleration)

max_force = np.max(force)
min_force = np.min(force)
time_of_max_force = np.argmax(force)
time_of_min_force = np.argmin(force)

max_deformation = np.max(deformation)
min_deformation = np.min(deformation)
time_of_max_deformation = np.argmax(deformation)
time_of_min_deformation = np.argmin(deformation)

# Вычисление площади под кривой ускорения и силы
area_acceleration = np.trapz(acceleration)
area_force = np.trapz(force)

# Вычисление среднего значения и стандартного отклонения для ускорения и силы
mean_acceleration = np.mean(acceleration)
std_acceleration = np.std(acceleration)

mean_force = np.mean(force)
std_force = np.std(force)

print("Ускорение")
print("Максимальное ускорение:", max_acceleration)
print("Время достижения максимального ускорения:", time_of_max_acceleration)
print("Минимальное ускорение:", min_acceleration)
print("Время достижения минимального ускорения:", time_of_min_acceleration)

print("\nСила")
print("Максимальная сила:", max_force)
print("Время достижения максимальной силы:", time_of_max_force)
print("Минимальная сила:", min_force)
print("Время достижения минимальной силы:", time_of_min_force)

print("\nДеформация")
print("Максимальная деформация:", max_deformation)
print("Время достижения максимальной деформации:", time_of_max_deformation)
print("Минимальная деформация:", min_deformation)
print("Время достижения минимальной деформации:", time_of_min_deformation)

print("\nИнтегральные параметры")
print("Площадь под кривой ускорения:", area_acceleration)
print("Площадь под кривой силы:", area_force)

print("\nСтатистика")
print(f"Среднее значение ускорения: {mean_acceleration:.2f}")
print(f"Стандартное отклонение ускорения: {std_acceleration:.2f}")
print(f"Среднее значение силы: {mean_force:.2f}")
print(f"Стандартное отклонение силы: {std_force:.2f}")
    

Задание 9

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

10.07.23 11.07.23 12.07.23 13.07.23 14.07.23
Нижний Новгород 1000000 2000000 2500000 3000000 2150000
Астрахань 1560000 2330000 2500000 3990000 2150000
Самара 2120000 2500000 3770000 2650000 4000000
Москва 2589000 2990000 4488000 4586000 3500000
Воронеж 2100000 2599000 3100000 2110000 4233000
Санкт-Петербург 1533000 2660000 4220000 3500000 2577000

Напишите программу, которая определит:

  • Город с максимальной выручкой.
  • Дату наибольшей выручки.

Пример вывода:

        Город с наибольшей выручкой: Москва
День с наибольшей выручкой: 13.07.23

    

Решение:

        import numpy as np

revenue = np.array([[1000000, 2000000, 2500000, 3000000, 2150000],
                    [1560000, 2330000, 2500000, 3990000, 2150000],
                    [2120000, 2500000, 3770000, 2650000, 4000000],
                    [2589000, 2990000, 4488000, 4586000, 3500000],
                    [2100000, 2599000, 3100000, 2110000, 4233000],
                    [1533000, 2660000, 4220000, 3500000, 2577000]])
cities = np.array(['Нижний Новгород', 'Астрахань', 'Самара', 'Москва', 'Воронеж', 'Санкт-Петербург'])
days = np.array(['10.07.23', '11.07.23', '12.07.23', '13.07.23', '14.07.23'])

# Находим город с наибольшей суммарной выручкой
total_revenue = np.sum(revenue, axis=1)
max_revenue_city = cities[np.argmax(total_revenue)]
print('Город с наибольшей выручкой:', max_revenue_city)

# Находим день с наибольшей выручкой
max_revenue_day = days[np.argmax(np.max(revenue, axis=0))]
print('День с наибольшей выручкой:', max_revenue_day)

    

Задание 10

Имеются массивы с данными о продажах:

        years = np.random.choice(range(2011, 2023), size=100000)
sales = np.random.randint(500, 125000, size=100000)
revenue = np.random.randint(1000000, 50000000, size=100000)

    

Напишите программу, которая определит:

  • Общее количество продаж по каждому году.
  • Среднюю выручку по каждому году.
  • Год с максимальным числом продаж.
  • Год с минимальной выручкой.

Пример вывода:

        Общее количество продаж
в 2011 году: 515147911
в 2012 году: 515179236
в 2013 году: 528064407
в 2014 году: 517416072
в 2015 году: 527501756
в 2016 году: 538125332
в 2017 году: 522721395
в 2018 году: 525814794
в 2019 году: 518083325
в 2020 году: 520183365
в 2021 году: 531273592
в 2022 году: 524972288

Средняя выручка
в 2011 году: 25704926.10
в 2012 году: 25219581.33
в 2013 году: 25578527.41
в 2014 году: 25712459.61
в 2015 году: 25326597.70
в 2016 году: 25396822.60
в 2017 году: 25516990.28
в 2018 году: 25346759.66
в 2019 году: 25283882.80
в 2020 году: 25723706.84
в 2021 году: 25462308.43
в 2022 году: 25350071.26

Год с максимальным количеством продаж: 2017
Год с минимальной выручкой от продаж: 2019

    

Решение:

        import numpy as np

# Генерация случайных данных о продажах
years = np.random.choice(range(2011, 2023), size=100000)
sales = np.random.randint(500, 125000, size=100000)
revenue = np.random.randint(1000000, 50000000, size=100000)

sales_data = np.column_stack((years, sales, revenue))

# Находим общее количество продаж за каждый год
total_sales_by_year = np.zeros((12,))
for i in range(12):
    total_sales = np.sum(sales_data[sales_data[:, 0] == (2011 + i), 1])
    total_sales_by_year[i] = total_sales

print("Общее количество продаж")
for i, year in enumerate(range(2011, 2023)):
    print(f"в {year} году: {int(total_sales_by_year[i])}")

# Вычисляем среднюю выручку от продажи за каждый год
average_revenue_by_year = np.zeros((12,))
for i in range(12):
    average_revenue = np.mean(sales_data[sales_data[:, 0] == (2011 + i), 2])
    average_revenue_by_year[i] = average_revenue

print("\nСредняя выручка")
for i, year in enumerate(range(2011, 2023)):
    print(f"в {year} году: {average_revenue_by_year[i]:.2f}")

# Определяем год с максимальным количеством продаж
max_sales_year = sales_data[:, 0][np.argmax(sales_data[:, 1])]
print(f"\nГод с максимальным количеством продаж: {max_sales_year}")

# Определяем год с минимальной выручкой от продажи
min_revenue_year = sales_data[:, 0][np.argmin(sales_data[:, 2])]
print(f"Год с минимальной выручкой от продаж: {min_revenue_year}")

    

Подведем итоги

NumPy – мощная и эффективная библиотека, обладающая двумя важными преимуществами:

  • Обширным набором функций для работы с многомерными массивами, которые могут описывать любые данные – от производственных показателей и курсов валют до изображений и видео.
  • Высокой скоростью обработки данных (благодаря реализации на C/C++).

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

В заключительной главе самоучителя будем изучать Pandas.

***

Содержание самоучителя

  1. Особенности, сферы применения, установка, онлайн IDE
  2. Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
  3. Типы данных: преобразование и базовые операции
  4. Методы работы со строками
  5. Методы работы со списками и списковыми включениями
  6. Методы работы со словарями и генераторами словарей
  7. Методы работы с кортежами
  8. Методы работы со множествами
  9. Особенности цикла for
  10. Условный цикл while
  11. Функции с позиционными и именованными аргументами
  12. Анонимные функции
  13. Рекурсивные функции
  14. Функции высшего порядка, замыкания и декораторы
  15. Методы работы с файлами и файловой системой
  16. Регулярные выражения
  17. Основы скрапинга и парсинга
  18. Основы ООП: инкапсуляция и наследование
  19. Основы ООП: абстракция и полиморфизм
  20. Графический интерфейс на Tkinter
  21. Основы разработки игр на Pygame
  22. Основы работы с SQLite
  23. Основы веб-разработки на Flask
  24. Основы работы с NumPy
  25. Основы анализа данных с Pandas

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
DevOps
Санкт-Петербург, от 150000 RUB до 400000 RUB
Продуктовый аналитик в поддержку
по итогам собеседования
PHP Developer
от 200000 RUB до 270000 RUB

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ