Как перебрать массив в python
Перейти к содержимому

Как перебрать массив в python

NumPy, часть 2: базовые операции над массивами

Здравствуйте! Я продолжаю работу над пособием по python-библиотеке NumPy.

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

Сегодня мы познакомимся с операциями над массивами.

Базовые операции

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

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

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

NumPy также предоставляет множество математических операций для обработки массивов:

Полный список можно посмотреть здесь.

Многие унарные операции, такие как, например, вычисление суммы всех элементов массива, представлены также и в виде методов класса ndarray.

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

Индексы, срезы, итерации

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

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

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

b[i] можно читать как b[i, <столько символов ‘:’, сколько нужно>]. В NumPy это также может быть записано с помощью точек, как b[i, . ].

Например, если x имеет ранг 5 (то есть у него 5 осей), тогда

  • x[1, 2, . ] эквивалентно x[1, 2, :, :, :],
  • x[. , 3] то же самое, что x[:, :, :, :, 3] и
  • x[4, . , 5, :] это x[4, :, :, 5, :].

Итерирование многомерных массивов начинается с первой оси:

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

Манипуляции с формой

Как уже говорилось, у массива есть форма (shape), определяемая числом элементов вдоль каждой оси:

Форма массива может быть изменена с помощью различных команд:

Порядок элементов в массиве в результате функции ravel() соответствует обычному «C-стилю», то есть, чем правее индекс, тем он «быстрее изменяется»: за элементом a[0,0] следует a[0,1]. Если одна форма массива была изменена на другую, массив переформировывается также в «C-стиле». Функции ravel() и reshape() также могут работать (при использовании дополнительного аргумента) в FORTRAN-стиле, в котором быстрее изменяется более левый индекс.

Метод reshape() возвращает ее аргумент с измененной формой, в то время как метод resize() изменяет сам массив:

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

Объединение массивов

Несколько массивов могут быть объединены вместе вдоль разных осей с помощью функций hstack и vstack.

hstack() объединяет массивы по первым осям, vstack() — по последним:

Функция column_stack() объединяет одномерные массивы в качестве столбцов двумерного массива:

Аналогично для строк имеется функция row_stack().

Разбиение массива

Используя hsplit() вы можете разбить массив вдоль горизонтальной оси, указав либо число возвращаемых массивов одинаковой формы, либо номера столбцов, после которых массив разрезается «ножницами»:

Функция vsplit() разбивает массив вдоль вертикальной оси, а array_split() позволяет указать оси, вдоль которых произойдет разбиение.

Копии и представления

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

Вообще никаких копий

Простое присваивание не создает ни копии массива, ни копии его данных:

Python передает изменяемые объекты как ссылки, поэтому вызовы функций также не создают копий.

Представление или поверхностная копия

Разные объекты массивов могут использовать одни и те же данные. Метод view() создает новый объект массива, являющийся представлением тех же данных.

Предисловие переводчика

Продолжаем перевод статьи о numpy в python. Для тех кто не читал первую часть, сюда: Часть 1. А всем остальным — приятного чтения.

Другие пути создания массивов

Функция arange аналогична функции range, но возвращает массив:

Функции zeros и ones создают новые массивы с установленной размерностью, заполненные этими значениями. Это, наверное, самые простые в использовании функции для создания массивов:

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

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

Функция eye возвращает матрицу с единичками на к-атой диагонали:

Математические операции над массивами

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

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

При несоответствии в размере выбрасываются ошибки:

Однако, если размерность массивов не совпадает, они будут преобразованы для выполнения математических операций. Это зачастую означает, что меньший массив будет использован несколько раз для завершения операций. Рассмотрим такой пример:

Тут, одномерный массив b был преобразован в двухмерный, который соответствует размеру массива a. По существу, b был повторен несколько раз, для каждой «строки» a. Иначе его можно представить так:

Python автоматически преобразовывает массивы в этом случае. Иногда, однако, когда преобразование играет роль, мы можем использовать константу newaxis, чтобы изменить преобразование:

Вдобавок к стандартным операторам, в numpy включена библиотека стандартных математических функций, которые могут быть применены поэлементно к массивам. Собственно функции: abs, sign, sqrt, log, log10, exp, sin, cos, tan, arcsin, arccos, arctan, sinh, cosh, tanh, arcsinh, arccosh, и arctanh.

Функции floor, ceil и rint возвращают нижние, верхние или ближайшие (округлённое) значение:

Также в numpy включены две важные математические константы:

Перебор элементов массива

Проводить итерацию массивов можно аналогично спискам:

Для многомерных массивов итерация будет проводиться по первой оси, так, что каждый проход цикла будет возвращать «строку» массива:

Множественное присваивание также доступно при итерации:

Базовые операции над массивами

Для получения каких-либо свойств массивов существует много функций. Элементы могут быть суммированы или перемножены:

В этом примере были использованы функции массива. Также можно использовать собственные функции numpy:

Для большинства случаев могут использоваться оба варианта.
Некие функции дают возможность оперировать статистическими данными. Это функции mean (среднее арифметическое), вариация и девиация:

Можно найти минимум и максимум в массиве:

Функции argmin и argmax возвращают индекс минимального или максимального элемента:

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

Как и списки, массивы можно отсортировать:

Значения в массиве могут быть «сокращены», чтобы принадлежать заданному диапазону. Это тоже самое что применять min(max(x, minval), maxval) к каждому элементу x:

Уникальные элементы могут быть извлечены вот так:

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

Вот и вторая статья подошла к концу. Спасибо за уделенное внимание и удачи в ваших начинаниях! До скорой встречи.

Цикл for и функция range в Python

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

Содержание страницы:
1.1. Цикл for в Python
1.2. Аргумент end фунции print
1.3. Действия во время выполнения цикла for
1.4. Основные ошибки с циклом for
2.1. Встроенная функция range
2.2. Создание числового списка с помощью функции range
2.4. Перебор списка по индексам с помощью функции range
3. Генераторы списков

1. Цикл for в Python.

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

>>> cars = ['ford', 'opel', 'audi', 'land rover', 'bmw']
>>> for brend in cars :
. print(brend) # отступ в 4 пробела
.
ford
opel
audi
land rover
bmw

Во второй строке кода определяется цикл for . Python берет каждую торговую марку из списка и сохраняет его в переменной brend. После двоеточия код на следующей строке должен начинается с 4 пробелами. С помощью функции print, название марки выводится в переменной brand. Затем код повторяется до тех пор, пока не закончатся элементы в списке.

1.2. Аргумент end фунции print .

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

>>> cars = ['ford', 'opel', 'audi', 'land rover', 'bmw']
>>> for brend in cars :
. print(brend, end=' ') # отступ в 4 пробела
.
ford opel audi land rover bmw

Аргумент end записывается в виде end= ' ' . Какое количество пробелов вы укажите, такое и будет после выводится между переменными.

1.3. Действия во время выполнения цикла for .

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

>>> cars = ['ford', 'opel', 'audi', 'land rover', 'bmw']
>>> for brend in cars :
. print(f"Автомобили торговой марки очень надежные")
.
Автомобили торговой марки Ford очень надежные
Автомобили торговой марки Opel очень надежные
Автомобили торговой марки Audi очень надежные
Автомобили торговой марки Land Rover очень надежные
Автомобили торговой марки Bmw очень надежные

Со строками цикл for работает также как и со списком.

>>> mesage = 'Hello World!'
>>> for i in mesage :
. print(i * 5, end=' ')
.
HHHHH eeeee lllll lllll ooooo WWWWW ooooo rrrrr lllll ddddd .

1.4. Основные ошибки с циклом for .

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

  • Пропущенный отступ.

>>> mesage = 'Hello World!'
>>> for i in mesage :
. print(i * 5, end=' ') # нет отступа в 4 пробела
File "<stdin>", line 2
print(i * 5, end=' ')
^
IndentationError: expected an indented block

Для устранения этой ошибки, достаточно поставить в следующей строке после команды for 4 пробела. В основном, если вы работаете в любом современном текстовом редакторе, то после двоеточия он сам поставит отступы на следующей строке.

  • Лишний отступ.
  • Пропущенное двоеточие.

2. 1. Встроенная функция range .

Встроенная функция range() используется для построения числовых последовательностей. В примере используем команду for и функцию range для выполнения ровно 10 итераций с выводом значения от 0 до 10.

>>> for x in range(10) :
. print(x, end=' ')
.
0 1 2 3 4 5 6 7 8 9

При передаче только одного аргумента, последовательность будет начинаться с 0 и до значения аргумента (10), не включая его. Одна из самых распространённых ошибок, это когда разработчик предполагает, что значение аргумента функции range включается в сгенерированную последовательность.

Приведем пример с двумя аргументами. Выведем последовательность от 20 до 30.

>>> for x in range(20, 30) :
. print(x, end=' ')
.
20 21 22 23 24 25 26 27 28 29

2.2. Создание числового списка с помощью функции range .

  • С помощью функции range удобно строить числовые списки.

>>> numbers = list( range(5, 25) )
>>> print(numbers)
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

  • Функция range может создавать последовательности, пропуская числа в заданном диапазоне. Например, приведем пример построения списка от 0 до 100, с шагом 15.

>>> numbers = list( range(0, 100, 15) )
>>> print(numbers)
[0, 15, 30, 45, 60, 75, 90]

  • С помощью цикла for и функции range можно создавать практически любой числовой список. К примеру, создадим список квадратов всех числе от 1 до 10. Операция возведения в степень обозначается двумя звездочками ( ** ).

>>> a = []
>>> for i in range(1, 11) :
. a.append(i**2)
.
>>> print(a)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

На каждом цикле переменная возводится в квадрат и добавляется в список.

2.4. Перебор списка по индексам с помощью функции range

С помощью цикла for и функции range список можно перебирать по индексам и с каждым значением в списки, производить любые операции. Приведем пример, перебора списка по индексам, с помощью функции range и функции len, которая определяет длину списка.

>>> list_1 = [1, 3, 5, 10, 12, 20]
>>> for index in range ( len (list_1)):
. list_1[ index ] += 100
.
>>> print(list_1)
[101, 103, 105, 110, 112, 120]

В начале определим длину списка с помощью функции len . Затем это значение передается функции range . В нашем примере длина списка равна 6. С каждым проходом цикла for, index принимает значения от 0 до 6 (не включая 6). В теле цикла мы вызываем список list_1 и обращаемся к элементам списка по индексам, равные значению переменной index . Каждое значение индекса мы увеличивает на 100. Затем с помощью функции print выводим список на экран и видим что все значения увеличены на 100.

С помощью индексов и функции range мы можем объединять информацию из разных списков. В примере ниже мы имеем список с именами, а второй список с фамилиями. Выведем на экран имя и фамилию:

>>> list_4 = ['Artem', 'Serg', 'Georgy', 'Petr']
>>> list_5 = ['Ivanov', 'Petrov', 'Sidorov', 'Ulyanov']
>>> for index in range ( len (list_4)):
. print(list_4[ index ], list_5[ index ])
.
Artem Ivanov
Serg Petrov
Georgy Sidorov
Petr Ulyanov

В результате получили общие данные на экране.

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

>>> list_1 = [1, 3, 5, 10, 12, 20]
>>> list_2 = [20, -9, 42, 10, 755, 12]
>>> list_3 = [12, 85, 96, 155, 235, 12]
>>> list_new = []
>>> for index in range ( len (list_1)):
. list_new.append(list_1[ index ] * list_2[ index ] * list_3[ index ])
.
>>> print(list_new)
[240, -2295, 20160, 15500, 2129100, 2880]

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

Важно помнить, что программа будет работать, если вы уверены, что списки одинаковой длины. Проверить это вы всегда можете с помощью встроенной функции len .

3. Генераторы списков в Python .

Состоящий выше пример построения квадратов чисел в разделе 2.2 состоял из нескольких строк кода. Генератор списка позволяет сгенерировать тот же список, но всего в одной строке. Определите название списка, после откройте квадратные скобки. Запишите выражение для значений, в нашем случает i ** 2. Затем напишите цикл for для генерирования чисел, которые будут передаваться выражению и закройте квадратные скобки.

>>> a = [i ** 2 for i in range(1,11)]
>>> print(a)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

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

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