能否使用sympy符号对numpy数组进行索引?

3

你好,我想对类似这样的numpy数组进行一些求和操作

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

但是我遇到了一个错误。是否有可能将numpy符号作为numpy数组索引进行处理?如果不能,您能给我提供一个解决方案吗? 谢谢。


为什么需要使用符号求和?您想要使用这些符号的任何属性吗?在我看来,普通求和就是您所需的:sum(sum(a))。内部的 sum 对列求和,第二个对行求和。如果您对相反的情况感兴趣,可以使用 sum(sum(a.transpose()) - juandesant
juandesat说我有一个像素数组,形状为(row,col),用numpy数组表示,然后我将其分成以每个P(i,j)为中心的33像素块,其中P(i,j)是整个numpy数组中的像素点(i,j)。我想要的是计算每个33块图像的平均像素值作为P(i,j)的新值,因此"i"和"j"将是动态的。该数组只是一个示例,但我想要使用sympy符号作为numpy数组的指数。谢谢。 - Narcisse Doudieu Siewe
我甚至可以换个角度来问我的问题:例如,是否有可能将sympy符号的值作为Python整数值获取? - Narcisse Doudieu Siewe
1
SymPy函数通常在SymPy对象(例如Symbol实例)上操作。通常您会以符号方式构建一个方程,然后使用lambdify生成一个回调函数,该回调函数可以在numpy数组上运行。 - Bjoern Dahlgren
2个回答

5

您不能直接在SymPy表达式中使用numpy对象,因为numpy对象不知道如何处理符号变量。

相反,使用SymPy对象创建您想要的符号,然后使用lambdify进行转换。 numpy数组的SymPy版本是IndexedBase,但似乎存在错误,因此,由于您的数组是二维的,您还可以使用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

请注意,创建整数符号的正确语法是symbols('i j', integer=True),而不是symbols('i j', Integer=True)
请注意,必须使用a[i, j]而不是不支持的a[i][j]

2

MatrixSymbol仅限于二维矩阵。为了推广到任意维度的数组,您可以使用IndexedBase生成表达式。目前lambdifyIndexedBase不兼容,但可以与DeferredVectors一起使用。因此,技巧是将DeferredVector传递给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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接