将 SymPy 矩阵转换为 numpy 数组/矩阵的最佳方法是啥
Posted
技术标签:
【中文标题】将 SymPy 矩阵转换为 numpy 数组/矩阵的最佳方法是啥【英文标题】:What is the best way to convert a SymPy matrix to a numpy array/matrix将 SymPy 矩阵转换为 numpy 数组/矩阵的最佳方法是什么 【发布时间】:2013-06-08 19:45:14 【问题描述】:我不确定我在sympy
中使用的将MutableDenseMatrix
转换为numpy.array
或numpy.matrix
的方法是否是当前的良好做法。
我有一个符号矩阵,如:
g = sympy.Matrix( [[ x, 2*x, 3*x, 4*x, 5*x, 6*x, 7*x, 8*x, 9*x, 10*x],
[x**2, x**3, x**4, x**5, x**6, x**7, x**8, x**9, x**10, x**11]] )
我正在转换为 numpy.array
做:
g_func = lambda val: numpy.array( g.subs( x:val ).tolist(), dtype=float )
我在哪里得到一个给定值 x
的数组。
SymPy 中是否有更好的内置解决方案来做到这一点?
谢谢!
【问题讨论】:
这个问题的大部分都在这里 ***.com/questions/10678843/… 得到回答 - 我知道这不是完全相同的问题,但它提供了关于 numpy/sympy 互操作性的所有必要信息。 谢谢!感觉要准备一个答案,因为我认为这也是我的案例的最佳方法...... 是的,使用lambdify
(我现在懒得写答案)。
【参考方案1】:
此答案基于 Krastanov 和 asmeurer 的建议。这个小sn-p使用sympy.lambdify:
from sympy import lambdify
from sympy.abc import x, y
g = sympy.Matrix([[ x, 2*x, 3*x, 4*x, 5*x, 6*x, 7*x, 8*x, 9*x, 10*x],
[y**2, y**3, y**4, y**5, y**6, y**7, y**8, y**9, y**10, y**11]])
s = (x, y)
g_func = lambdify(s, g, modules='numpy')
其中g
是您的表达式,其中包含分组在s
中的所有符号。
如果使用modules='numpy'
,函数g_func
的输出将是一个np.ndarray
对象:
g_func(2, 3)
#array([[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
# [ 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147]])
g_func(2, y)
#array([[2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
# [y**2, y**3, y**4, y**5, y**6, y**7, y**8, y**9, y**10, y**11]], dtype=object)
如果modules='sympy'
输出是sympy.Matrix
对象。
g_func = lambdify(vars, g, modules='sympy')
g_func(2, 3)
#Matrix([[2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
# [9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147]])
g_func(2, y)
#Matrix([[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
# [y**2, y**3, y**4, y**5, y**6, y**7, y**8, y**9, y**10, y**11]])
【讨论】:
【参考方案2】:从SymPy-0.7.6.1_mpmath_ matrix docs,存在tolist()
方法:
最后,可以将矩阵转换为嵌套列表。这非常有用,因为大多数涉及矩阵或数组的 Python 库(即 NumPy 或 SymPy)都支持这种格式:
B.tolist()
【讨论】:
mpmath.matrices.matrices.tolist()
返回mpmath.ctx_mp_python.mpf
的列表,因此您仍然需要强制转换它,但是 IMO 这不是 OP 所要求的,因为他们想要一个生成 numpy 数组的函数,这就是接受的答案的作用。【参考方案3】:
numpy.array(SympyMatrix.tolist()).astype(numpy.float64)
原生的tolist
方法将 sympy 矩阵变成嵌套索引的东西
numpy.array
可以将嵌套索引的内容转换为数组
.astype(float64)
会将数组的数字转换为默认的 numpy 浮点类型,这将与任意 numpy 矩阵操作函数一起使用。
作为附加说明 - 值得一提的是,通过强制转换为 numpy,您将失去执行矩阵运算的能力,同时保留 sympy 变量和表达式以备不时之需。
编辑: 我的补充说明的一点是,在转换为 numpy.array 时,您失去了在矩阵中的任何位置拥有变量的能力。你所有的矩阵元素必须在你施法之前已经是数字,否则一切都会破坏。
【讨论】:
我猜 .tolist() 不是必需的。 (由@turtles_are_cute 回答证明)【参考方案4】:这看起来是最直接的:
np.array(g).astype(np.float64)
如果你跳过 astype 方法,numpy 将创建一个 'object' 类型的矩阵,它不适用于常见的数组操作。
【讨论】:
它有效。而 np.array(g, dtype=np.float64) 不会。以上是关于将 SymPy 矩阵转换为 numpy 数组/矩阵的最佳方法是啥的主要内容,如果未能解决你的问题,请参考以下文章