【问题标题】:How to multiply matricies with algebra in numpy如何在numpy中将矩阵与代数相乘
【发布时间】:2021-07-15 22:55:40
【问题描述】:

我的代码中有两个 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 包以这种方式返回它们。

【问题讨论】:

  • “我知道不建议使用 numpy 矩阵对象”是什么意思?通常不推荐,还是在某些情况下像您这样?
  • 我不想为其赋值的变量 -- numpy 不会这样做。
  • @j1-lee Numpy 矩阵对象通常不被推荐,它们仍然存在的唯一原因是与 scipy 的东西交互,一般意图是最终删除 numpy.matrix 类。有关 numpy 文档的更多信息
  • np.matrix 的使用无关紧要。这里的问题是数字和字符串的乘法。 1.0*'l1'
  • @CharlesKelly 哦,我明白了,我什至不知道np.matrix 的存在。我以为你的意思是np.array。谢谢你澄清它。我今天学到了一些新东西:)

标签: python numpy matrix linear-algebra


【解决方案1】:

对于对象 dtype 数组,np.dot 之类的函数尝试将操作委托给元素的 multiply 和 add 方法。

因此我定义了一个类:

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。如果没有,我希望您需要定义自己的类。

    【讨论】:

    • 创建我自己的类是我的初衷,但我认为会有一个功能比仅使用基本循环和比较来构建我的输出矩阵更有效。我去看看 sympy,谢谢
    猜你喜欢
    • 2021-06-06
    • 1970-01-01
    • 2020-08-27
    • 2020-11-05
    • 2015-08-29
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多