我一直在寻找一种紧凑的方法来创建一个矩阵,该矩阵将相同的函数应用于来自不同大小的不同可迭代对象的元素。假设一个是尺寸m = 3,另一个是尺寸n = 4
a = range(3)
b = range(4)
这只是最简单的示例,因为我可以随意使用numpy向量进行相同的操作。
我想以这种方式填充矩阵:
yawn = np.zeros((len(a), len(b)), dtype='float')
meh = lambda x, y: np.exp(x + y) / (1 + np.exp(x + y))
for i in a:
for j in b:
yawn[i,j] = meh(i,j)
预期的结果确实是:
array([[ 0.5 , 0.73105858, 0.88079708, 0.95257413],
[ 0.73105858, 0.88079708, 0.95257413, 0.98201379],
[ 0.88079708, 0.95257413, 0.98201379, 0.99330715]])
我尝试使用np.vectorize()或np.fromfunction()之类的东西,但是我接近了:
meh_vec = np.vectorize(meh)
meh_vec(a, 3)
array([ 0.95257413, 0.98201379, 0.99330715])
但是我可以弄清楚是否有办法做这样的事情:
meh_vec(a, b)
这不会导致ValueError:
ValueError:操作数不能与形状(3,)一起广播 (4,)
此外我读到:
提供矢量化功能主要是为了方便,而不是 性能。实现本质上是一个for循环。
是否有一种变通方法,它可能比for循环更紧凑,更快速?
答案 0 :(得分:3)
将它们转换为可相互广播的# Define two helper variables
z = m.addVar(name="z")
h = m.addVar(name="h")
m.addConstr(h == y[0]-y[1]) # h = y[0]-y[1]
m.addConstr(z == abs_(h)) # z == |h| == | y[0] - y[1] |
m.setObjectiveN(z, 1) # Maximize z = |h| = |y[0]-y[1]|
数组,从而得到具有open
的结果2D
数组-
np.ix_
或者,为了更加明确,我们可以使用In [57]: x,y = np.ix_(a,b)
In [58]: np.exp(x + y) / (1 + np.exp(x + y))
Out[58]:
array([[0.5 , 0.73105858, 0.88079708, 0.95257413],
[0.73105858, 0.88079708, 0.95257413, 0.98201379],
[0.88079708, 0.95257413, 0.98201379, 0.99330715]])
在输入的数组版本上手动扩展尺寸-
None/np.newaxis
为进一步优化,我们可能要存储In [64]: a = np.arange(3)
...: b = np.arange(4)
In [65]: np.exp(a[:,None] + b) / (1 + np.exp(a[:,None] + b))
Out[65]:
array([[0.5 , 0.73105858, 0.88079708, 0.95257413],
[0.73105858, 0.88079708, 0.95257413, 0.98201379],
[0.88079708, 0.95257413, 0.98201379, 0.99330715]])
并重新用于除法。另外,np.exp(a[:,None] + b)
可以重写为a[:,None] + b
,因为这基本上是一个外部添加。