Переформатирование, изменение формы — Python: Numpy-массивы
Часто разработчикам приходится изменять размеры массивов. Например, переформатировать исходные данные, чтобы разделить их на подмассивы. В некоторых случаях требуется еще и объединять многомерные данные в единый массив значений. Чтобы решать такие задачи, массивы numpy.ndarray предоставляют набор методов, самым популярным из которых является метод reshape() .
В этом уроке разберем, как работать с размерами массивов numpy.ndarray и как получать их производные. Еще поговорим об ограничениях размерности и узнаем, как они помогают оптимизировать работу.
Как изменить размер массива
Представим, что нам нужно увеличить размер массива numpy.ndarray . Для этого будем идти по следующим шагам:
- Узнаем размер массива и индексы вдоль оси
- Изменим размер массива
Рассмотрим каждый этап подробнее.
Как узнать размер массива и индексы вдоль оси
Чтобы изменить размер numpy.ndarray , нужно узнать его значение. Для этого используют атрибут shape :
import numpy as np one_dimension_array = np.array( [0,1,2,3,4,5,6,7,8,9,10,11] ) print(one_dimension_array.shape) # => (12,) two_dimensions_array = np.array( [ [0,1,2], [3,4,5], [6,7,8], [9,10,11] ] ) print(two_dimensions_array.shape) # => (4, 3) three_dimensions_array = np.array( [ [ [0,1], [2,3], ], [ [4,5], [6,7], ], [ [8,9], [10,11] ] ] ) print(three_dimensions_array.shape) # => (3, 2, 2)
В примере выше атрибут shape возвращает кортеж целых чисел. Длина кортежа указывает на размерность массива:
- (12,) — одномерный массив
- (4, 3) — двумерный массив
- (3, 2, 2) — трехмерный массив
Числа в кортеже означают количество элементов по конкретной оси индексов:
- (12,) — 12 значений
- (4, 3) — четыре блока значений по три значения в каждом
- (3, 2, 2) — три блока значений, каждый из которых состоит из двух блоков по два значения
Название ось индексов отсылает к декартовой системе координат. Вспомним ее основные правила:
- Чтобы построить отрезок или другой одномерный объект, достаточно одной координатной оси
- Чтобы построить квадрат или другой двумерный объект, необходима координатная плоскость из двух перпендикулярных осей
- Чтобы построить куб или другой трехмерный объект, нужно три ортогональные оси координат
Теперь, когда мы знаем размер исходного массива, можно изменять его форму. Для этого используем метод reshape() .
Как изменить размер массива с помощью метода reshape()
В Python используется метод reshape() , с помощью которого можно получить двухмерный и трехмерный массив из одномерного. Этот обязательный параметр ожидает новый размер данных, к которому нужно переформатировать исходный массив.
Попробуем получить двумерный массив two_dimensions_array из одномерного массива one_dimension_array . Для этого используем метод reshape() с новым размером данных (4, 3) :
print(one_dimension_array.reshape((4, 3))) # => [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]]
Чтобы получить трехмерный массив three_dimensions_array , достаточно также указать нужный размер:
print(one_dimension_array.reshape((3, 2, 2))) # => [[[ 0 1] # [ 2 3]] # [[ 4 5] # [ 6 7]] # [[ 8 9] # [10 11]]]
Изменять форму массива можно не только от данных меньшей размерности к данным большей размерности. Это можно делать и в обратную сторону.
Попробуем получить исходный одномерный массив one_dimension_array из двумерного массива two_dimensions_array :
print(two_dimensions_array.reshape((12,))) # => [ 0 1 2 3 4 5 6 7 8 9 10 11]
А тут переформатируем three_dimensions_array в two_dimensions_array :
print(three_dimensions_array.reshape((4,3))) # => [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]]
Необязательно уменьшать размер последовательно. Например, можно из трехмерного массива получить сразу одномерный:
print(three_dimensions_array.reshape((12,))) # => [ 0 1 2 3 4 5 6 7 8 9 10 11]
С помощью атрибута shape можно узнать размерность массива numpy.ndarray . А метод reshape поможет ее уменьшить или увеличить. Однако у этого массива есть ограничения по размеру данных — его нужно соблюдать, чтобы оптимизировать выполнения методов над массивами.
Какие размеры массива допустимы
У массива numpy.ndarray есть ограничения по размеру данных — по осям индексов должны быть данные одного размера. Это ограничение позволяет оптимизировать выполнения методов над массивами. Рассмотрим на примере.
Допустим, нам нужно сконвертировать список из списков длиной три и два:
np.array( [ [0,1,2], [3,4,], ] ) # => [list([0, 1, 2]) list([3, 4])]
На первый взгляд у нас получился массив numpy.ndarray . Но если внимательно посмотреть на элементы, мы увидим, что получились списки, а не ожидаемые целочисленные массивы. Это ограничит дальнейшую работу с данными, потому что поведение многих методов меняется.
Попробуем найти в данном массиве максимальный элемент 4 . Это приведет к такому результату:
print(np.array( [ [0,1,2], [3,4,], ] ).max()) # => [3, 4]
В этом примере мы получили не тот результат, которого ожидали.
Numpy старается предотвращать некорректные действия — для этого в нем есть система предупреждений и подсказок. Но это не значит, что не нужно следить за размером массива. Он играет важную роль в реализации методов библиотеки Numpy, поэтому рекомендуем обращать внимание на этот момент.
В случае с методом reshape() Numpy вообще не дает совершить некорректную конвертацию массива из 12 элементов в массив из 15 элементов — три блока по пять значений. В этом случае он вызывает исключение:
one_dimension_array.reshape(3,5) # => ValueError: cannot reshape array of size 12 into shape (3,5)
Ограничения по размеру могут добавить неудобств, когда мы увеличиваем или уменьшаем размерность массива. При этом они позволяют не указывать некоторые значения размера, когда мы хотим его изменить.
Как сделать автоматический расчет размера массива
Ограничения на размер массива позволяют не указывать некоторые размеры в методе reshape() . Это можно оставить на автоматический расчет. Для этого нужное значение размерности поменяем на -1 :
print(one_dimension_array.reshape((4,3))) print(one_dimension_array.reshape(((4, -1)))) print(one_dimension_array.reshape(((-1, 3)))) # => [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]]
Все преобразования в примере выше дают одинаковый результат. Необходимый размер рассчитывается автоматически, исходя из количества элементов.
Для массивов большей размерности это работает по такому же принципу:
print(one_dimension_array.reshape((3, 2, 2))) print(one_dimension_array.reshape((-1, 2, 2))) print(one_dimension_array.reshape((3, -1, 2))) print(one_dimension_array.reshape((3, 2, -1))) # => [[[ 0 1] # [ 2 3]] # [[ 4 5] # [ 6 7]] # [[ 8 9] # [10 11]]]
Чтобы получить одномерный массив и использовать автоматический расчет, не нужно находить количество элементов. Строки в примере ниже дают одинаковый результат:
print(three_dimensions_array.reshape((12,))) print(three_dimensions_array.reshape((-1,))) # => [ 0 1 2 3 4 5 6 7 8 9 10 11]
Теперь вы знаете, как определять размерность массива. Вы умеете изменять размер и рассчитывать его автоматически. Чтобы закрепить знания на практике, рассмотрим еще один пример.
Как размер массива меняется на практике
Изменение формы массива помогает подготовить исходные данные — после такой обработки их будет удобнее анализировать и преобразовывать.
Представим сервис платформы продаж, который логирует данные по сетевым магазинам в конце рабочего дня в определенном порядке. Аналитики выгрузили данные из закрытого контура платформы. Так они получили 28 значений подневных продаж сети:
orders = [7, 1, 7, 8, 4, 2, 4, 5, 3, 5, 2, 3, 8, 12, 8, 7, 15, 11, 13, 9, 21, 18, 17, 21, 25, 16, 25, 17,] shops_number = 4 orders_matrix = np.array(orders) orders_matrix = orders_matrix.reshape(-1, shops_number) print(orders_matrix) # => [[ 7 1 7 8] # [ 4 2 4 5] # [ 3 5 2 3] # [ 8 12 8 7] # [15 11 13 9] # [21 18 17 21] # [25 16 25 17]] print(orders_matrix.shape) # => (7, 4)
Полученный массив данных можно визуализировать в виде такой таблицы:
День | Магазин №1 | Магазин №2 | Магазин №3 | Магазин №4 |
---|---|---|---|---|
0 | 7 | 1 | 7 | 8 |
1 | 4 | 2 | 4 | 5 |
2 | 3 | 5 | 2 | 3 |
3 | 8 | 12 | 8 | 7 |
4 | 15 | 11 | 13 | 9 |
5 | 21 | 18 | 17 | 21 |
6 | 25 | 16 | 25 | 17 |
Выводы
Метод shape — важный атрибут для структурного описания массива numpy.ndarray . Он помогает узнать размер вдоль каждой оси.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Как форматировать позиции элементов двумерного массива при выводе?
Подскажите пожалуйста, есть ли в Python методы, позволяющие выравнивать элементы в двумерном массиве, в зависимости от количества знаков в этом элементе? Например, у меня есть матрица случайных чисел размерностью МхМ (М вводит пользователь), диапазон чисел — от 1 до 50. Я хочу, чтобы при выводе все элементы в каждом столбце были выравнены по правому краю относительно друг друга. Т.е, делаю 3 отступа, если элемент — это однозначное число, и 2 отступа, если двузначное. Сделал это через if .. else, но может быть есть более лаконичный и красивый способ? заранее спасибо
from random import randint M = int(input('Please enter the size of matrix: ')) matrix = [[randint(1, 50) for _ in range(M)] for _ in range(M)] for i in range(M): for j in range(M): if matrix[i][j] '.format(matrix[i][j]), end=' ') else: print(' <>'.format(matrix[i][j]), end=' ') print()
Отслеживать
задан 11 авг 2020 в 20:03
43 5 5 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
for i in range(M): for j in range(M): print('2d>'.format(matrix[i][j]), end=' ')
Отслеживать
26k 4 4 золотых знака 21 21 серебряный знак 36 36 бронзовых знаков
Массивы (матрицы) в Python
Python — популярный и динамический язык программирования. Он позволяет решать разные задачи по разработке ПО, при выполнении которых часто используются массивы.
С их помощью вы сможете добавить однотипные данные и избежать дублирования кода.
Одномерные массивы в Python представляют собой список элементов. Значения указываются внутри квадратных скобок, где перечисляются через запятую. Как правило, любой элемент можно вызвать по индексу и присвоить ему новое значение.
Массив строк в Python:
Prime = ['string1', 'string2', 'string3'] Prime[1] = 'string2'; //trueЧтобы возвратить число элементов внутри списка, используют функцию len() :
len(Prime) == 4; // trueКогда нужно перечислить элементы массива, применяют цикл for . В «Питоне» этот цикл перебирает элементы, а не индексы, как в Pascal:
for elem in [1, 4, 67]Идём дальше. Создать и добавить цикл в Python можно с помощью генератора заполнения списков. Записывается он в следующем виде: [значение массива for имя переменной in число элементов];
Если говорить про создание не одномерного, а двумерного массива, то он в Python создаётся путём использования вложенных генераторов, и выглядит это так:
[[0 for j in range(m)] for i in range(n)]
Как создаются матрицы в Python?
Добавление и модификация массивов или матриц (matrix) в Python осуществляется с помощью библиотеки NumPy. Вы можете создать таким образом и одномерный, и двумерный, и многомерный массив. Библиотека обладает широким набором пакетов, которые необходимы, чтобы успешно решать различные математические задачи. Она не только поддерживает создание двумерных и многомерных массивов, но обеспечивает работу однородных многомерных матриц.
Чтобы получить доступ и начать использовать функции данного пакета, его импортируют:
import numpy as npФункция array() — один из самых простых способов, позволяющих динамически задать одно- и двумерный массив в Python. Она создаёт объект типа ndarray :
array = np.array(/* множество элементов */)Для проверки используется функция array.type() — принимает в качестве аргумента имя массива, который был создан.
Если хотите сделать переопределение типа массива, используйте на стадии создания dtype=np.complex :
array2 = np.array([ /*элементы*/, dtype=np.complex)Когда стоит задача задать одномерный или двумерный массив определённой длины в Python, и его значения на данном этапе неизвестны, происходит его заполнение нулями функцией zeros() . Кроме того, можно получить матрицу из единиц через функцию ones() . При этом в качестве аргументов принимают число элементов и число вложенных массивов внутри:
np.zeros(2, 2, 2)К примеру, так в Python происходит задание двух массивов внутри, которые по длине имеют два элемента:
array([ [[0, 0]] [[0, 0]]] )Если хотите вывести одно- либо двумерный массив на экран, вам поможет функция print() . Учтите, что если матрица слишком велика для печати, NumPy скроет центральную часть и выведет лишь крайние значения. Дабы увидеть массив полностью, используется функция set_printoptions() . При этом по умолчанию выводятся не все элементы, а происходит вывод только первой тысячи. И это значение массива указывается в качестве аргумента с ключевым словом threshold.
Базовые операции в NumPy
Все действия, производимые над компонентами массива, оборачиваются созданием нового массива. При этом массивы и матрицы взаимодействуют в том случае, если имеют один и тот же размер:
array1 = np.array([[1, 2, 3], [1, 2, 3]]) array2 = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])Если выполнить array1 + array2, компилятор скажет об ошибке, а всё потому, что размер первого matrix равен двум, а второго трём.
array1 = np.array([1, 2, 5, 7]) array2 = arange([1, 5, 1])В данном случае array1 + array2 вернёт нам массив со следующими элементами: 2, 4, 8, 11. Здесь не возникнет ошибки, т. к. матрицы имеют одинаковые размеры. Причём вместо ручного сложения часто применяют функцию, входящую в класс ndarray sum() :
np.array(array1 + array1) == array1 + array2В ndarray входит большая библиотека методов, необходимых для выполнения математических операций.
Форма матрицы в Python
Lenght matrix (длина матрицы) в Python определяет форму. Длину матрицы проверяют методом shape() .
Массив с 2-мя либо 3-мя элементами будет иметь форму (2, 2, 3). И это состояние изменится, когда в shape() будут указаны аргументы: первый — число подмассивов, второй — размерность каждого подмассива.
Те же задачи и ту же операцию выполнит reshape() . Здесь lenght и другие параметры matrix определяются числом столбцов и строк.
Есть методы и для манипуляции формой. Допустим, при манипуляциях с двумерными или многомерными массивами можно сделать одномерный путём выстраивания внутренних значений последовательно по возрастанию. А чтобы поменять в матрице строки и столбцы местами, применяют transpose() .
Операции со срезами matrix в Python
Часто мы работаем не с целым массивом, а с его компонентами. Эти операции выполняются с помощью метода слайс (срез). Он пришел на замену циклу for, при котором каждый элемент подвергался перебору. Метод позволяет получать копии matrix, причём манипуляции выполняются в виде [start:stop:step] . В данном случае start — индекс элемента, с которого берётся отсчёт, stop — последний элемент, step — размер шага или число пропускаемых значений элемента при каждой итерации. Изначально start равен нулю, stop — индексу последнего элемента, step — единице. Если выполнить операции без аргументов, копирование и добавление списка произойдёт полностью.
Допустим, имеем целочисленный массив otus = [1, 2, 3, 4] . Для копирования и вывода используем otus[:] . В итоге произойдёт вывод последовательности [1, 2, 3, 4]. Но если аргументом станет отрицательное значение, допустим, -2, произойдёт вывод уже других данных:
otus[-2]; //[4]Возможны и другие операции. Например, если добавить ещё одно двоеточие, будет указан шаг копируемых элементов. Таким образом, otus[::2] позволит вывести матрицу [1, 3].
Если ввести отрицательное значение, к примеру, [::-2] отсчёт начнётся с конца, и в результате произойдёт вывод [3, 1]. Остаётся добавить, что метод среза позволяет гибко работать с матрицами и вложенными списками в Python.
Хотите узнать гораздо больше? Записывайтесь на курс «Разработчик Python»!
Как форматировать элементы матрицы в питоне
Формат ввода
В первой строке подаются высота и ширина холста – натуральные числа w и h (1 ≤ w, h ≤ 100); во второй – целое число n, количество прямоугольников (0 ≤ n ≤ 5000). Затем программа получает n строк с координатами левого верхнего и правого нижнего углов прямоугольников – x1, y1, x2, y2.
Формат вывода
Целое число – площадь незакрашенной поверхности холста.
Примеры ввода и вывода
Формат ввода
Строка с числами n и m, разделенными пробелом.
Формат вывода
Матрица, заполненная в соответствии с условием задачи.
Пример ввода и вывода
Формат ввода
В первой строке подается число n – количество строк. Затем программа получает n строк с элементами матрицы.
Формат вывода
Максимальный элемент из заштрихованной области матрицы.
Пример ввода и вывода
Пример ввода и вывода
[1, 3, 3, 1]
Решение
def trianglePascal(n): if n == 0: return [1] else: st = trianglePascal(n - 1) return [1] + [st[i] + st[i+1] for i in range(n - 1)] + [1] n = int(input()) print(trianglePascal(n))
n = int(input()) li = [1] for i in range(n): for j in range(len(li) - 1): li[j] = li[j] + li[j + 1] li.insert(0, 1) print(li)
from math import factorial n = int(input()) print([int(factorial(n) / (factorial(j) * factorial(n - j))) for j in range(n + 1)])
l = [1] for _ in range(int(input())): l = [a + b for a, b in zip([*l, 0], [0, *l])] print(l)
import math def fac(num): return math.factorial(num) def pasc(n): row = [1] for i in range(1, n + 1): row.append(int(fac(n) / (fac(i) * fac(n - i)))) return row n = int(input()) print(pasc(n))
Материалы по теме
- Словари в Python: 12 задач для начинающих с решениями
- 5 задач с решениями на Python для начинающих разработчиков
- 5 классических задач по Python для начинающих с решениями