#python #numpy #matrix #linear-algebra
Вопрос:
В моем коде есть два объекта матрицы numpy, один из которых представляет собой матрицу чисел, а другой-матрицу переменных, которым я не хочу присваивать значения. Результат, которого я хочу, таков:
[[ 1., 0., 0., 0., 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 1., -1., 1., -1.],
[ 0., 0., 1., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 1., -1.],
[ 0., 0., 0., 0., 1., -1., 0., 0., 1.]]
multiplied by the column vector
[['i8'],
['i4'],
['i9'],
['i5'],
['i2'],
['i1'],
['i7'],
['i6'],
['i3']]
Gives:
[[ i8 i1],
[i4 i1-i7 i6-i3],
[ i9 i1],
[ i5 i6-i3],
[ i2-i1 i3]]
Я просмотрел раздел линейной алгебры numpy и не смог найти ничего, что работало бы. Я пробовал использовать np.dot(), np.multiply(), пытался преобразовать их в массивы, и я продолжаю получать ошибку типа соответствия подписи (я предполагаю, что это связано с тем, что вторая матрица состоит из строк). Как я могу умножить их, чтобы получить свои уравнения?
- Я знаю, что использовать объекты матрицы numpy не рекомендуется, причина, по которой они реализованы здесь, заключается в том, что пакет python, который я использую для получения этих матриц, возвращает их таким образом.
Комментарии:
1. Что вы подразумеваете под «Я знаю, что использование объектов матрицы numpy не рекомендуется»? Это вообще не рекомендуется или в некоторых контекстах, подобных вашему?
2. переменные, которым я не хочу присваивать значения -numpy этого не делает.
3. @j1-ли Объекты матрицы Numpy вообще не рекомендуются, единственная причина, по которой они все еще существуют, — это взаимодействие с материалами scipy, общее намерение состоит в том, чтобы в конечном итоге удалить класс numpy.matrix. более подробная информация содержится в документах numpy
4. Использование
np.matrix
не имеет значения. Проблема здесь заключается в умножении чисел и строк.1.0*'l1'
5. @CharlesKelly О, я понимаю, я даже не знал
np.matrix
, что существует. Я думал, ты имеешь в видуnp.array
. Спасибо, что разъяснили это. Сегодня я узнал кое-что новое 🙂
Ответ №1:
С массивами типов dtype объектов такие функции, как np.dot
попытка делегировать действие методам умножения и добавления элементов.
Таким образом, я определяю класс:
In [467]: class Y:
...: def __init__(self,astr):
...: self.value = astr
...: def __repr__(self):
...: return self.value
...: def __mul__(self, other):
...: if other==0:
...: return Y('')
...: elif other==1:
...: return self
...: elif other==-1:
...: return Y('-' self.value)
...: else:
...: return Y(str(other) self.value)
...: def __add__(self, other):
...: if self.value=='':
...: return other
...: elif other.value=='':
...: return self
...: else:
...: return Y(self.value ' ' other.value)
...:
и создайте массив объектов:
In [468]: y = np.array([Y('i1'),Y('i8'),Y('j3')])
In [469]: y
Out[469]: array([i1, i8, j3], dtype=object)
с учетом этого dot
выглядит разумно.
In [470]: np.dot(y,[-1,0,1])
Out[470]: -i1 j3
In [471]: type(_)
Out[471]: __main__.Y
Y
возможно, потребуется некоторая настройка, но это дает основную идею.
Но имейте в виду, что все это умножение и сложение происходит в Python. Ничего из этого не компилируется, так что в его скорости нет ничего особенного.
И с вашими массивами, немного подправленными:
In [474]: In [437]: x = np.array([[ 1., 0., 0., 0., 0., 1., 0., 0., 0.],
...: ...: [ 0., 1., 0., 0., 0., 1., -1., 1., -1.],
...: ...: [ 0., 0., 1., 0., 0., 1., 0., 0., 0.],
...: ...: [ 0., 0., 0., 1., 0., 0., 0., 1., -1.],
...: ...: [ 0., 0., 0., 0., 1., -1., 0., 0., 1.]], dtype=int)
...: ...:
...: ...: #multiplied by the column vector
...: ...:
...: ...: y = np.array([['i8'],
...: ...: ['i4'],
...: ...: ['i9'],
...: ...: ['i5'],
...: ...: ['i2'],
...: ...: ['i1'],
...: ...: ['i7'],
...: ...: ['i6'],
...: ...: ['i3']])
...:
In [475]: x
Out[475]:
array([[ 1, 0, 0, 0, 0, 1, 0, 0, 0],
[ 0, 1, 0, 0, 0, 1, -1, 1, -1],
[ 0, 0, 1, 0, 0, 1, 0, 0, 0],
[ 0, 0, 0, 1, 0, 0, 0, 1, -1],
[ 0, 0, 0, 0, 1, -1, 0, 0, 1]])
In [476]: y
Out[476]:
array([['i8'],
['i4'],
['i9'],
['i5'],
['i2'],
['i1'],
['i7'],
['i6'],
['i3']], dtype='<U2')
In [477]: y = np.frompyfunc(Y,1,1)(y)
In [478]: y
Out[478]:
array([[i8],
[i4],
[i9],
[i5],
[i2],
[i1],
[i7],
[i6],
[i3]], dtype=object)
и точка:
In [479]: np.dot(y.T,x.T)
Out[479]:
array([[i8 i1, i4 i1 -i7 i6 -i3, i9 i1, i5 i6 -i3, i2 -i1 i3]],
dtype=object)
Ответ №2:
Ваше предположение верно: умножение матриц не определено для нечисловых типов. У нас есть простая целочисленная репликация строк: «i5» * 2 дает «i5i5», а это не то, что вам нужно. Также обратите внимание, что вы используете коэффициенты с плавающей запятой, поэтому даже такая интерпретация недопустима.
Вы, кажется, работаете с символической линейной алгеброй. NumPy не имеет встроенных операций для этого домена. В зависимости от вашего приложения вы можете использовать sympy
. Если нет, я ожидаю, что вам нужно определить свой собственный класс.
Комментарии:
1. Создание собственного класса было моим первоначальным намерением, но я предположил, что для этого будет функция, которая будет намного эффективнее, чем просто использование базовых циклов и сравнений для построения моей выходной матрицы. Я посмотрю на сочувствие, спасибо