Библиотека NumPy предназначена для работы с многомерными массивам чисел.
В том числе с последовательностями и таблицами чисел.
Библиотека позволяет очень ёмко и быстро выполнять довольно обширный набор действий с массивами чисел.
Установка ПО
Нужно запустить cmd и ввести
pip install numpy pillow scikit-image matplotlib --user.
Или ещё можно запустить вот такую программу:
import os, sys
python = sys.executable
user = '--user' if 'venv' not in python else ''
cmd = '{} -m pip install numpy pillow scikit-image matplotlib --upgrade {}'.format(python, user)
print(cmd)
os.system(cmd)
На вход даются числа n и m.
Выведите массив размера n на m,
в котором в первой строчке (строка с нулевым индексом) идут числа от 0 до m-1, а остальные числа равны 0.
Тип элементов массива должен быть np.int8.
>>> x = np.arange(12).reshape(3, 4)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# Любая координата может быть срезом (:, a:b, ::-1, a:b:c)
# Строка с индексом 1
>>> x[1, :]
array([4, 5, 6, 7])
# Столбец с индексом 2
>>> x[:, 2]
array([ 2, 6, 10])
# Строка в обратном порядке
>>> x[0, ::-1]
array([3, 2, 1, 0])
D: Сбитый прицел
На вход даются числа n, r, c.
Выведите массив размера n на n, в котором
в строке r и столбце c стоят 1, а остальные числа равны 0.
Тип элементов массива должен быть таким, чтобы во-первых, числа выводились как целые, без точек.
А во-вторых, чтобы при выводе при помощи repr конкретный тип не указывался.
В документации можно увидеть список возможных типов.
На вход даются числа n, m, r, c.
Выведите массив размера n на m, в котором
в котором в каждой r-ой строчке и в каждом c-ом столбце стоят 0, а остальные элементы равны 1.
>>> x = np.arange(12).reshape(3, 4)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# Вместо конкретного индекса можно передать набор индексов
>>> x[:, [1, 3]]
array([[ 1, 3],
[ 5, 7],
[ 9, 11]])
# Все передаваемые наборы должны быть одинаковой длины
>>> x[[0, 1], [1, 3]]
array([1, 7])
>>> x[np.arange(3), np.arange(3)]
array([ 0, 5, 10])
BC: Задачи B и C без циклов
решить способен теперь юный падаван. Сосредоточься.
Почувствуй numpy течение.
Строчки достаточно одной, чтобы из массива нулевого нужный сделать.
Ты должен сразиться с B и C ещё раз.
Тогда, только тогда джедаем будешь ты.
H: Разлиновка
На вход даётся число n. В следующей строке идёт несколько чисел. Выведите массив размера n на n,
в котором в строках с перечисленными выше индексами стоят 1.
>>> x = np.arange(12).reshape(2, 6)
# Можно ко всем элементам массива прибавлять числа и другие массивы
>>> x + 10
array([[10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21]])
# Можно все элементы массива умножать на числа или поэлементно на другие массивы
>>> x * 3
array([[ 0, 3, 6, 9, 12, 15],
[18, 21, 24, 27, 30, 33]])
# Если формы массивов не одинаковые, то происходит "размножение" вдоль координат с размерностью 1
# Например к массиву формы (2, 6) прибавляем массив формы (6) = (1, 6).
# Вдоль координаты 1 (то есть построчно) происходит размножение
>>> x + np.array([0, 10, 100, -10, -100, 0])
array([[ 0, 11, 102, -7, -96, 5],
[ 6, 17, 108, -1, -90, 11]])
# Например к массиву формы (2, 6) прибавляем массив формы (2, 1)
# Вдоль координаты 1 (то есть по столбцам) происходит размножение
>>> x + np.array([[0], [-100]])
array([[ 0, 1, 2, 3, 4, 5],
[-94, -93, -92, -91, -90, -89]])
>>> x + np.array([0, -100]).reshape((2, 1))
array([[ 0, 1, 2, 3, 4, 5],
[-94, -93, -92, -91, -90, -89]])
# Это самое размножение называется broadcasting, тема достаточно сложная.
# Если вы ничего не поняли, то можно для начала запомнить, что к массиву формы
# (m, n) можно построчно прибавить массив формы (1, n)
# или постолбцово прибавить массив формы (m, 1)
# Можно ко всем элементам массива применять различные функции, в том числе логические
>>> np.sqrt(np.abs(x))
array([[ 0. , 1. , 1.4142, 1.7321, 2. , 2.2361],
[ 2.4495, 2.6458, 2.8284, 3. , 3.1623, 3.3166]])
>>> x > 3
array([[False, False, False, False, True, True],
[ True, True, True, True, True, True]], dtype=bool)
>>> (x > 3) & (x < 8)
array([[False, False, False, False, True, True],
[ True, True, False, False, False, False]], dtype=bool)
I: Скалярное произведение
На вход даются два массива векторов \(v_i\) и \(w_i\).
Вычислите их скалярные произведения \((v_i, w_i)\).
Дан массив действительных чисел. Отнормируйте (X -> aX+b) его так, чтобы все числа лежали на отрезке [0,1] и значения 0 и 1 принимались.
Гарантируется, что в массиве есть хотя бы два различных числа.
Даны три массива действительных чисел \(a_i, b_i, c_i\) длины n.
Выведите два массива размера n корней квадратных уравнений \(a_i x^2 + b_i x + c_i\).
Гарантируется, что у каждого уравнения есть два корня.
Сначала должны выводиться корни, в которых вычитается корень из дискриминанта.
>>> x = np.arange(12).reshape(2, 6)
# Находить минимумы и максимумы, а также индексы соответствующих элементов бесконечно просто
>>> x = np.random.randint(0, 10, 10)
>>> x
array([8, 2, 8, 3, 4, 8, 9, 9, 3, 1])
>>> x.max(), x.min(), x.argmax(), x.argmin()
(9, 1, 6, 9)
# Если массив многомерный, то argmax и argmin возвращают не координату в массиве, а номер по порядку
>>> x = np.random.randint(0, 10, (2, 6))
>>> x
array([[1, 4, 9, 6, 6, 7],
[9, 8, 9, 5, 2, 7]])
>>> x.argmax()
2
# Но его можно превратить в координату в массиве
>>> np.unravel_index(x.argmax(), x.shape)
(0, 2)
# А также найти все наборы координат по заданному правилу
>>> np.argwhere(x==x.max())
array([[0, 2],
[1, 0],
[1, 2]], dtype=int64)
O: Заменить все максимумы
Дан массив действительных чисел.
Замените все значения, равные максимальному, на -1.
np.array([4, 8, 7, 5, 1, 6, 1, 1, 8, 5])
array([ 4, -1, 7, 5, 1, 6, 1, 1, -1, 5])
P: Ближайшее
Дан массив действительных чисел и некоторое число.
Найдите ближайшее по модулю к этому числу значение в массиве и его индекс.
Выведите массив максимальных значений в каждой строчке,
а за ним массив максимальных значений в каждом столбце.
np.array([[80, 85, 61],
[57, 41, 22]])
array([85, 57])
array([80, 85, 61])
R: Среднее, построчное и постолбцовое среднее
Дан прямоугольный массив действительных чисел X.
Выведите три массива: массив X, у которого из каждого элемента вычли
а) среднее арифметическое всех чисел массива X;
б) среднее арифметическое всех чисел данной строчки массива X;
в) среднее арифметическое всех чисел данного столбца массива X;
Дан линейный массив действительных чисел X.
Отсортируйте его.
np.array([1, 9, 2, 8, 3, 7])
array([1, 2, 3, 7, 8, 9])
T: argsort
Дан линейный массив действительных чисел X.
Выведите массив индексов, обладающих следующим свойством: в позиции i стоит индекс элемента массива X, который окажется i-ым, если массив отсортировать.
np.array([1, 9, 2, 8, 3, 7])
array([0, 2, 4, 5, 3, 1])
U: argsort — 2
Даны три линейных массива одинаковой длины. В первом массиве хранятся стоимости брусков, во втором – длины, а в третьем – массы. Отсортируйте массивы так, чтобы данные по брускам шли в порядке возрастания стоимости.
Картинки можно хранить в памяти компьютера как прямоугольную таблицу пикселей.
Каждый пиксель — это одно число, если картинка чернобелая, либо тройка чисел — яркости красного, зелёного и синего (RGB).
V: Порядок индексов
Даны числа W и H — ширина и высота картинки в пикселях.
Создайте подходящий массив, в котором можно хранить трёхцветную картинку данной ширины и высоты.
При этом данные в памяти должны храниться так, чтобы сначала шли три цвета одного пикселя,
затем цвета следующего пикселя в этой же строчке или первый пиксель из следующей строчки.
Каждый элемент должен быть однобайтным беззнаковым целым числом (np.uint8).
В питоне можно очень легко прочитать картинку в NumPy-массив:
from skimage import io
img = io.imread('30x60c.png')
Посмотреть на прочитанную картинку:
io.imshow(img)
io.show()
И записать картинку из NumPy-массива в файл:
io.imsave('res.png', img)
W: Размер картинки
В файле input.png сохранена картинка.
Прочитайте её в NumPy-массив.
Картинка может быть чёрно-белой или цветной.
Выведите её размеры: сначала ширину в пикселях, а затем высоту.
30
60
30
60
X: Зелёный слой
Из файла input.png прочитайте цветную картинку.
Извлеките из неё зелёный слой (получится двумерный массив) и сохраните в файл output.png (получится чёрно-белое изображение в котором координаты всех цветов равны координатам зелёного).
Y: Состыковка — 1
Из файла input.png прочитайте ч/б картинку.
В файл output.png запишите картинку, полученную из двух таких картинок состыковкой «одна над другой».
Z: Состыковка — 2
Из файла input.png прочитайте цветную картинку.
В файл output.png запишите картинку, полученную из двух таких картинок состыковкой «плечо к плечу».
ZA: Удаление — 1
Из файла input.png прочитайте ч/б картинку.
В файл output.png запишите картинку, полученную из исходной удалением по центру вертикальной полосы шириной в 10 пикселей.
Гарантируется, что ширина картинки не меньше 12 пикселей и чётна.
ZB: Удаление — 2
Из файла input.png прочитайте цветную картинку.
В файл output.png запишите картинку, полученную из исходной удалением по центру горизонтальной полосы высотой в 20 пикселей,
затем удалением вертикальной полосы шириной в 10 пикселей от $\frac{3}{4}W-5$ до $\frac{3}{4}W+4$ включительно ($W$ — это ширина картинки).
Гарантируется, что высота картинки не меньше 22 пикселей, ширина не меньше 12 пикселей, а также то, что высота чётна и (ширина − 10) делится на 4.
ZC: Вставка — 1
Из файла input.png прочитайте ч/б картинку.
В файл output.png запишите картинку, полученную из исходной вставкой по центру белой вертикальной полосы шириной в 10 пикселей.
ZD: Вставка — 2
Из файла input.png прочитайте цветную картинку.
В файл output.png запишите картинку, полученную из исходной вставкой по центру зелёной горизонтальной полосы высотой в 10 пикселей, затем вставкой красной вертикальной полосы шириной в 17 пикселей так, чтобы пространство слева было в два раз шире пространства справа.
ZE: Удвоение картинки
Из файла input.png прочитайте цветную картинку.
В файл output.png запишите картинку, увеличенную в два раза.
Если размер исходной картинки $(H,W)$, то размер новой должен быть $(2H-1,2W-1)$.
Получается картинка следующим образом.
Сначала между каждыми двумя столбцами записываем новый столбец — сумму их половинок.
Потом между каждыми двумя строками получившейся картинки тоже запишем новую строку — сумму половинок.