问题
Helle I want to do some summation on a numpy array like this
import numpy as np
import sympy as sy
import cv2
i, j = sy.symbols('i j', Integer=True)
#next read some grayscale image to create a numpy array of pixels
a = cv2.imread(filename)
b = sy.summation(sy.summation(a[i][j], (i,0,1)), (j,0,1)) #double summation
but I'm facing with an error. is it possible to handle numpy symbols as numpy arrays'indexes? if not can you sugest me a solution? Thanks.
回答1:
You can't use numpy object directly in SymPy expressions, because numpy objects don't know how to deal with symbolic variables.
Instead, create the thing you want symbolically using SymPy objects, and then lambdify it. The SymPy version of a numpy array is IndexedBase, but it seems there is a bug with it, so, since your array is 2-dimensional, you can also use MatrixSymbol.
In [49]: a = MatrixSymbol('a', 2, 2) # Replace 2, 2 with the size of the array
In [53]: i, j = symbols('i j', integer=True)
In [50]: f = lambdify(a, Sum(a[i, j], (i, 0, 1), (j, 0, 1)))
In [51]: b = numpy.array([[1, 2], [3, 4]])
In [52]: f(b)
Out[52]: 10
(also note that the correct syntax for creating integer symbols is symbols('i j', integer=True), not symbols('i j', Integer=True)).
Note that you have to use a[i, j] instead of a[i][j], which isn't supported.
回答2:
MatrixSymbol is limited to 2-dimensional matrices. To generalize to arrays of
any dimension, you can generate the expression with IndexedBase. lambdify is
currently incompatible with IndexedBase, but it can be used with
DeferredVectors. So the trick is pass a DeferredVector to lambdify:
import sympy as sy
import numpy as np
a = sy.IndexedBase('a')
i, j, k = sy.symbols('i j k', integer=True)
s = sy.Sum(a[i, j, k], (i, 0, 1), (j, 0, 1), (k, 0, 1))
f = sy.lambdify(sy.DeferredVector('a'), s)
b = np.arange(24).reshape(2,3,4)
result = f(b)
expected = b[:2,:2,:2].sum()
assert expected == result
来源:https://stackoverflow.com/questions/36282172/is-it-possible-to-index-numpy-array-with-sympy-symbols