我试图在numpy中做一些简单的事情,我确信应该有一个简单的方法。
基本上,我有一个不同长度的n
向量列表。如果v1[i]
是第一个向量的i
条目,那么我想找到一个n
- 维数组A,这样
A[i,j,k...] = v1[i] v2[j] v3[k] ...
我的问题是:
outer
只需要两个 vector 参数。
einsum
需要一个类似" abcd ..."的参数。这似乎是不必要的。
kron
需要看似相当复杂的重塑,并且只需要两个参数。
我希望避免尽可能多的复杂性,以避免引入错误。所以最好我想要一个命令。
到目前为止,我所掌握的最好的是:
vs = [v1, v2, v3 ...]
shape = map(len, vs)
# specify the orientation of each vector
newshapes = diag(array(shape)-1)+1
reshaped = [x.reshape(y) for x,y in zip(vs, newshapes)]
# direct product
A = reduce(lambda a,b: a*b, reshaped, 1)
答案 0 :(得分:8)
您可以使用以下一行代码:
reduce(np.multiply, np.ix_(*vs))
np.ix_()
将执行外部广播,您需要减少,但是您可以在没有lambda函数的情况下传递ufunc np.multiply
。
以下是比较:
import numpy as np
vs = [np.r_[1,2,3.0],np.r_[4,5.0],np.r_[6,7,8.0]]
shape = map(len, vs)
# specify the orientation of each vector
newshapes = np.diag(np.array(shape)-1)+1
reshaped = [x.reshape(y) for x,y in zip(vs, newshapes)]
# direct product
A = reduce(lambda a,b: a*b, reshaped, 1)
B = reduce(np.multiply, np.ix_(*vs))
np.all(A==B)
重新:
True
答案 1 :(得分:2)
还有另一行代码:
reduce(np.multiply.outer, vs)
对于我来说,它比np.ix_(*vs)
更加透明,并且支持this question中的多维数组。
时间限制在公差范围内是相同的:
import numpy as np
from functools import reduce
def outer1(*vs):
return np.multiply.reduce(np.ix_(*vs))
def outer2(*vs):
return reduce(np.multiply.outer, vs)
v1 = np.random.randn(100)
v2 = np.random.randn(200)
v3 = np.random.randn(300)
v4 = np.random.randn(50)
%timeit outer1(v1, v2, v3, v4)
# 1 loop, best of 3: 796 ms per loop
%timeit outer2(v1, v2, v3, v4)
# 1 loop, best of 3: 795 ms per loop
np.all(outer1(v1, v2, v3, v4) == outer2(v1, v2, v3, v4))
# True