【问题标题】:Numpy: outer product of n vectorsNumpy:n 个向量的外积
【发布时间】:2013-06-16 22:38:12
【问题描述】:

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

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

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

我的问题是:

  1. outer 只接受两个 vector 参数。

  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)

【问题讨论】:

  • 直到运行时向量的数量是未知的?
  • @DarenW 是的,没错。
  • 我喜欢这个reduce(lambda a, b: a[..., np.newaxis] * b, vs),但我不确定这是否可以被视为“单个命令”。或者如果有更快的方法。
  • @jorgeca 不错。它绝对不会比我的方法慢。
  • 你看过 itertools.combinations 吗?

标签: python arrays numpy


【解决方案1】:

你使用下面一行代码:

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

np.ix_() 会做外部广播,你需要reduce,但是你可以在没有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 这可能是一个微不足道的改进,除非你的向量列表真的很长,但我认为 numpy 的 np.multiply.reduce(np-ix_(vs)) 可能会比 Python 构造更好。
【解决方案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

【讨论】:

  • 是的,我更喜欢使用它。
猜你喜欢
  • 2013-01-17
  • 2016-12-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
相关资源
最近更新 更多