Перейти к содержимому

Как создать пустую матрицу numpy

  • автор:

Как объявить пустой двумерный массив?

Как можно объявить двумерный массив размерностью x, y. Так не работает:

arr = [][] arr = [x][y] 

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

Отслеживать

51.6k 201 201 золотой знак 63 63 серебряных знака 245 245 бронзовых знаков

задан 9 сен 2019 в 13:00

607 2 2 золотых знака 7 7 серебряных знаков 31 31 бронзовый знак

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Можно использовать модуль Numpy — numpy.empty():

import numpy as np arr = np.empty((x,y), dtype="float32") 
In [47]: arr = np.empty((x,y), dtype="object") In [48]: arr Out[48]: array([[None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None]], dtype=object) In [49]: arr[1,1] = "XXXXX" In [50]: arr Out[50]: array([[None, None, None], [None, 'XXXXX', None], [None, None, None], [None, None, None], [None, None, None]], dtype=object) 

Функции автозаполнения, создания матриц и числовых диапазонов

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

np.array( [0]*10 ) # массив из 10 нулей np.array( [1]*15 ) # массив из 15 единиц np.array( [x for x in range(10)] ) # массив из чисел от 0 до 9

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

Функции автозаполнения элементов массива

Это только часть основных функций для создания массивов с заданными значениями. Использовать их достаточно просто. Например, так:

np.empty(10) # создание одномерного массива с произвольными числами np.empty(10, dtype='int16') np.empty((3, 2), dtype='float32') # возвращаетматрицу 3x2 стипомfloat32

Для функций eye и identity размерности указываются отдельными параметрами:

np.eye(4) # матрица 4х4 np.eye(4, 2) # матрица 4x2 np.identity(5) # матрица 5x5

Функции ones, zeros и full работают по аналогии с функцией empty:

np.zeros( (2, 3, 4) ) # нулевая матрица размерностью 2x3x4 np.ones( [4, 3], dtype='int8') # матрица 4x3 из единиц и типом int8 np.full((3, 2), -1) # матрица 3x2, состоящая из -1

Все эти функции работают быстрее, чем функция array с генератором списков языка Python. Поэтому их предпочтительно использовать при создании и инициализации массивов определенными значениями.

Функции создания матриц

Следующий полезный набор функций позволяет генерировать матрицы на основе списков или по определенным правилам.

Давайте посмотрим как работают эти функции.

np.mat('1 2 3 4') # создает матрицу 1x4 из строки np.mat('1, 2, 3, 4') # то же самое: создает матрицу 1x4 из строки np.mat('1 2; 3 4') # возвращает матрицу 2x2

Или же, вместо строк можно использовать список или кортеж:

np.mat([5, 4, 3]) np.mat( [(1,2,3), (4,5,6)])

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

np.mat( [(1,2,3), (4,5,6,7)])# ошибка, размерности не совпадают

Следующая функция позволяет формировать диагональные матрицы:

np.diag([1, 2, 3]) # диагональная матрица 3x3

Но, если ей передать двумерный список, то она возвратит одномерный массив из элементов, стоящих на главной диагонали:

np.diag([(1,2,3), (4,5,6), (7,8,9)]) # выделение элементов главной диагонали

Если же мы хотим сформировать диагональную матрицу из многомерных списков или массивов, то следует воспользоваться функцией

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

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

np.tri(4) # треугольная матрица 4x4 np.tri(4, 2) # треугольная матрица 4x2

Если нужно привести уже существующие матрицы к треугольному виду, то это можно сделать так:

a = np.array( [(1,2,3), (4,5,6), (7,8,9)] ) np.tril(a) # нижняя треугольная матрица размером 3x3 np.triu(a) # верхняя треугольная матрица размером 3x3

Если указать одномерный список:

np.tril([1,2,3])

то будет создана треугольная матрица 3×3 из строк [1, 2, 3].

Также функции tril и triu будут работать и с многомерными массивами:

np.tril([[[1,2,3], [4,5,6], [7,8,9]]]) np.tril([[[1,2,3], [4,5,6], [7,8,9]], [[10,20,30], [40,50,60], [70,80,90]], [[100,200,300], [400,500,600], [700,800,900]]])

В этом случае последние двумерные сечения будут приведены к треугольному виду.

Последняя функция этойгруппы формирует матрицу Вандермонда из одномерных списков или массивов:

np.vander([1,2,3]) # матрица Вандермонда 3x3

Функции формирования числовых диапазонов

Следующая группа функций, которые мы рассмотрим на этом занятии, служит для формирования числовых диапазонов. Что делают эти функции? Когда мы с вами изучали язык Python, то говорили о функции

range(Start, Stop, Step)

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

Давайте рассмотрим некоторые из них. Первая функция arrange довольно часто применяется в программах на Python. Она позволяет проходить заданный интервал с указанным шагом, например, так:

np.arange(5)# интервал [0; 5) с шагом 1 np.arange(1, 5)# интервал [1; 5) с шагом 1 np.arange(1, 5, 0.5) # интервал [1; 5) с шагом 0,5

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

np.arange(0, np.pi, 0.1)

Здесь все величины вещественные. Мы начинаем движение от значения 0 с шагом 0,1 пока не дойдем до значения пи (не включая его). И, далее, используя этот массив, можно вычислить синус или косинус от всех этих значений:

np.cos(np.arange(0, np.pi, 0.1))

Видите, как это удобно. Без пакета NumPyнам пришлось бы писать цикл и делать вычисление для каждого значения аргумента. А здесь мы сразу получаем готовый массив значений функции косинуса. Это работает гораздо быстрее циклов в Python.

Похожим образом работает и функция linspace. Она разбивает указанный интервал на равномерные отрезки и возвращает массив этих значений:

Мы указываем в качестве аргументов интервал [start; stop] и число отметок в этом интервале n. Если n = 0, то получим пустой массив. При n = 1 – значение start. При n = 2 – значения start и stop. При n> 2 равномерное разбиение интервала точками m = n-2. Например:

np.linspace(0, np.pi, 0) # пустой массив np.linspace(0, np.pi, 1) # одно значение 0 np.linspace(0, np.pi, 2) # два значения: 0 и pi np.linspace(0, np.pi, 3) # три значения: 0, pi/2, pi

В чем отличие linspace от arange? В arange мы указываем сами шаг движения по числовой оси. При этом число значений определяется граничными значениями. А в linspace мы задаем граничные значения и число делений, а шаг вычисляется автоматически.

Функции logspace и geomspace работают аналогичным образом. У них указываются граничные значения и число членов, а на выходе имеем массив из соответствующих величин. Например:

np.logspace(0, 1, 3) # значения: 1, sqrt(10), 10 np.logspace(0, 1, 4) # значения: 1, 2.15, 4.64, 10 np.geomspace(1, 4, 3) # значения: 1, 2, 4 np.geomspace(1, 16, 5) # значения: 1, 2, 4, 8, 16

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

Функции формирования массивов на основе данных

Рассмотрим следующую группу, связанную с формированием на основе уже имеющихся данных.

Изменение формы массивов, добавление и удаление осей

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

Изменение размерности массивов

Предположим, у нас имеется массив, состоящий из десяти чисел:

a = np.arange(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

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

a.shape = 2, 5 # массив размерностью 2x5

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

b = a.reshape(10) # массив [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

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

b[0] = -1

приведет к изменению соответствующего элемента массива a:

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

Об этом всегда следует помнить. Также следует помнить, что у свойства shape и метода reshape() размерность должна охватывать все элементы массива. Например, вот такая команда:

a.shape = 3, 3

приведет к ошибке, т.к. размерность 3×3 = 9 элементов, а в массиве 10 элементов. Здесь всегда должно выполняться равенство:

n1 x n2 x … x nN = число элементов массива

Но допускается делать так:

a.shape = -1, 2 # размерность 5x2

Отрицательное значение -1 означает автоматическое вычисление размерности по первой оси. По второй берется значение 2. В этом случае получим размерность 5×2.

То же самое можно делать и в методе reshape():

b.reshape(-1, 1) # размерность 10x1 b.reshape(1, -1) # размерность 1x10

Обратите внимание, в последних двух случаях мы получаем представления двумерных массивов, преобразуя одномерный. Это важный момент, так как на выходе метода reshape() получается матрица с двумя осями (строки и столбцы), тогда как изначально массив b имел только одну ось. Не случайно последнее представление отображается с двумя квадратными скобками:

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

Первая скобка – это первая ось (строка), а вторая скобка (вторая ось) описывает столбцы. Одномерный же массив b отображается с одной квадратной скобкой:

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

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

b.reshape(2, -1) # размерность 2x5 b.reshape(-1, 2) # размерность 5x2

Первое представление (2×5) отображается следующим образом:

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

Здесь снова мы видим две квадратные скобки (значит, массив двумерный). Первая описывает ось axis0, отвечающую за строки, а вложенные скобки описывают вторую ось axis1, отвечающую за столбцы.

Если нам требуется многомерный массив преобразовать в обычный одномерный, то можно воспользоваться методом ravel(), который возвращает новое представление, не меняя текущего:

c = b.ravel() # с ссылается на одномерное представление массива

Если же нам нужно текущий массив преобразовать в одномерный, то это можно сделать так:

b.shape = -1

Помимо свойства shape можно использовать метод resize, который выполняет подобную операцию с текущим массивом. Например:

a.resize(2, 5) # массив 2x5

Но, как мы уже говорили, вот такая строчка приведет к ошибке:

a.resize(3, 3) # ошибка: 3x3 != 10

Однако, мы все-таки можем выполнить такую операцию, указав дополнительно флаг refcheck=False:

a.resize(3, 3, refcheck=False) # массив 3x3
a.resize(4, 5, refcheck=False) # массив 4x5

В первом случае происходит удаление одного 10-го элемента, а во втором случае – добавление 4∙5 — 3∙3 = 11 нулей. Это очень удобно, когда нам нужно менять не только форму, но и размер самого массива.

Транспонирование матриц и векторов

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

a = np.array([(1, 2, 3), (1, 4, 9), (1, 8, 27)])

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

b = a.T

Обратите внимание, мы здесь создаем лишь новое представление тех же самых данных массива a. И изменение элементов в массиве b:

b[0, 1] = 10

приведет к соответствующему изменению значения элемента и массива a. Это следует помнить, используя операцию транспонирования.

Транспонирование векторов работает несколько иначе. Предположим, имеется одномерный массив:

x = np.arange(1, 10)

и мы выполняем операцию транспонирования:

В результате ничего не изменилось: вектор как был строкой, так строкой и остался. Почему? Дело в том, что массив x имеет только одну размерность, поэтому здесь нет понятия строк и столбцов. Соответственно, операция транспонирования ни к чему не приводит. Чтобы получить ожидаемый эффект, нужно добавить к массиву еще одну ось, например, так:

x.shape = 1, -1

И теперь, при транспонировании получим вектор-столбец:

x.T # вектор-столбец 9x1

Добавление и удаление осей

  • np.expand_dims(a, axis) – добавление новой оси;
  • np.squeeze(a[, axis]) – удаление оси (без удаления элементов).
x_test = np.arange(32).reshape(8, 2, 2) # массив 8x2x2

И нам потребовалось добавить еще одно измерение (ось), причем, в самое начало, то есть, ось axis0. Сейчас на этой оси 8 элементов – матриц 2×2, но мы хотим сделать четырехмерный массив, сохранив остальные три оси и их данные без изменений. Как раз это достаточно просто сделать с помощью функции expand_dims, следующим образом:

x_test4 = np.expand_dims(x_test, axis=0)

Обращаясь к свойству shape:

x_test4.shape # (1, 8, 2, 2)

Видим, что массив стал четырехмерным и первая добавленная ось axis0 содержит один элемент – трехмерный массив 8x2x2. При необходимости, мы всегда можем добавить новый элемент на эту ось:

a = np.append(x_test4, x_test4, axis=0) # размерность (2, 8, 2, 2)

или удалить ненужные элементы:

b = np.delete(a, 0, axis=0) # размерность (1, 8, 2, 2)

Здесь второй параметр 0 – индекс удаляемого элемента на оси axis0. Если нам нужно добавить последнюю ось в массиве, то для этого можно записать такую команду:

b = np.expand_dims(x_test4, axis=-1) # размерность (1, 8, 2, 2, 1)

Отрицательный индекс -1 – это следующая с конца ось. Если указать индекс -2, то добавится предпоследняя ось и так далее. Отрицательные индексы очень удобно использовать при работе с массивами произвольных размерностей. Следующая функция squeeze позволяет удалить все оси с одним элементом. Например, строчка:

c = np.squeeze(b) # размерность (8, 2, 2)

превращает массив размерностью (1, 8, 2, 2) в массив размерностью (8, 2, 2). При необходимости, дополнительно мы можем самостоятельно указать оси, которые следует удалять, например, так:

c = np.squeeze(b, axis=0) # удалит только ось axis0, не затронув другие

Но, если указать ось с числом элементов больше 1, то возникнет ошибка:

c = np.squeeze(b, axis=1) # ошибка, на оси axis1 8 элементов

Объект newaxis

В NumPy добавлять новые оси иногда удобнее с помощью специального объекта np.newaxis. Например, пусть у нас есть одномерный массив:

a = np.arange(1, 10) # array([1, 2, 3, 4, 5, 6, 7, 8, 9])

У него одна ось – одно измерение. Добавим еще одну ось, допустим, в начало. С помощью объекта np.newaxis это можно сделать так:

b = a[np.newaxis, :] # добавление оси axis0 b.shape # (1, 9)

Или, можно прописать сразу две оси:

c = a[np.newaxis, :, np.newaxis] c.shape # (1, 9, 1)

Как видите, это достаточно удобная операция.

Видео по теме

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

Массивы (матрицы) в Python

Python_Deep_14.3_site-5020-9131b4.png

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)]

matrix_python-20219-889f47.jpg

Как создаются матрицы в 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»!

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

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