10

我正在尝试在 numpy 中做一些简单的事情,我相信应该有一种简单的方法来做到这一点。

基本上,我有一个n不同长度的向量列表。如果v1[i]i第一个向量的第 'th 个条目,那么我想找到一个n维数组 A,这样

A[i,j,k...] = v1[i] v2[j] v3[k] ...

我的问题是:

  1. outer只需要两个向量参数。

  2. einsum需要像“abcd ...”这样的参数,这似乎是不必要的。

  3. 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)
4

2 回答 2

8

您使用以下一行代码:

reduce(np.multiply, np.ix_(*vs))

np.ix_()将进行外部广播,您需要减少,但您可以在np.multiply没有 lambda 函数的情况下传递 ufunc。

这是比较:

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
于 2013-06-17T00:34:26.830 回答
3

还有一行代码:

reduce(np.multiply.outer, vs)

对我来说,它比np.ix_(*vs)构造和支持多维数组更透明,比如这个问题

时序在公差范围内是相同的:

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
于 2016-12-11T11:46:56.810 回答