我有一个 SymPy 矩阵 M
In [1]: from sympy import *
In [2]: M = 1/10**6 * Matrix(([1, 10, 100], [1000, 10000, 100000]))
In [3]: M
Out[3]:
Matrix([
[1.0e-6, 1.0e-5, 0.0001],
[ 0.001, 0.01, 0.1]])
Run Code Online (Sandbox Code Playgroud)
我想打印四舍五入到 3 位小数的输出,如下所示:
In [3]: M
Out[3]:
Matrix([
[ 0.000, 0.000, 0.000],
[ 0.001, 0.010, 0.100]])
Run Code Online (Sandbox Code Playgroud)
在普通的 Python 中,我会这样:
In [5]: '{:.3f}'.format(1/10**6)
Out[5]: '0.000'
Run Code Online (Sandbox Code Playgroud)
但是如何在 SymPy 矩阵中做呢?
此外,更一般的情况是一个还包含符号的表达式
x = symbols('x')
M = 1/10**6 * Matrix(([1, 10*x, 100], [1000, 10000*x, 100000]))
Run Code Online (Sandbox Code Playgroud)
首选输出是
In [3]: M
Out[3]:
Matrix([
[ 0.000, 0.000*x, 0.000],
[ 0.001, 0.010*x, 0.100]])
Run Code Online (Sandbox Code Playgroud)
小智 6
要舍入表达式中的每个数字,请使用以下函数
def round_expr(expr, num_digits):
return expr.xreplace({n : round(n, num_digits) for n in expr.atoms(Number)})
Run Code Online (Sandbox Code Playgroud)
It can be applied to any SymPy expression, including matrices.
x = symbols('x')
M = 1/10**6 * Matrix(([1, 10*x, 100], [1000, 10000*x, 100000]))
round_expr(M, 3)
Run Code Online (Sandbox Code Playgroud)
yields
Matrix([
[ 0.0, 0, 0.0],
[0.001, 0.01*x, 0.1]])
Run Code Online (Sandbox Code Playgroud)
For numeric matrices, the following is simpler and preserves trailing zeros:
>>> M.applyfunc(lambda x: Symbol('{:.3f}'.format(x)))
Matrix([
[0.000, 0.000, 0.000],
[0.001, 0.010, 0.100]])
Run Code Online (Sandbox Code Playgroud)
Here, applyfunc applies the given function to each entry of M. A natural thing to try would be lambda x: '{:.3f}'.format(x) but SymPy matrices aren't really meant to hold strings: the strings get parsed back into numbers and the trailing zeros get dropped, resulting in
Matrix([
[ 0.0, 0.0, 0.0],
[0.001, 0.01, 0.1]])
Run Code Online (Sandbox Code Playgroud)
So I wrap each string in Symbol, thus making a new symbol out of it. Symbols can appear in matrices, and they printed as their names, in this case the names are "0.000" and so on.