我有一个包含元组所有组合的列表,每个元素只能是-1或1。该列表可以生成为:
N=2
list0 = [p for p in itertools.product([-1, 1], repeat=N)]
例如,如果元组具有N=2
个元素:
list0 = [(-1,-1),(-1,1),(1,-1),(1,1)]
因此,元组的总数为2^2=4
。
如果元组具有N=3
个元素:
list0 = [(-1,-1,-1),(-1,-1,1),(-1,1,-1),(-1,1,1), (1,-1,-1),(1,-1、1),(1、1,-1),(1、1、1)]
这是我的关注点
现在,我想获取列表中任何一对元组之间的点积的所有结果(包括一个自身的元组)。因此,对于N=2
,将有6(pairs) + 4(itself) = 10 combinations;
,对于N=3
,将是28(pairs) + 8(itself) = 36 combinations.
对于小型N
,我可以执行以下操作:
for x in list0:
for y in list0:
print(np.dot(x,y))
但是,假设我已经有了list0,那么如果N大(例如〜50),那么计算点积所有可能性的最佳方法是什么?
答案 0 :(得分:1)
您可以使用np.dot
本身:
import numpy as np
list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
# approach using np.dot
a = np.array(list0)
result = np.dot(a, a.T)
# brute force approach
brute = []
for x in list0:
brute.append([np.dot(x, y) for y in list0])
brute = np.array(brute)
print((brute == result).all())
输出
True
您要问的是documentation中a
与自身的矩阵乘法:
如果a和b均为二维数组,则为矩阵乘法,
请注意,最 pythonic 解决方案是使用运算符@
:
import numpy as np
list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
# approach using np.dot
a = np.array(list0)
result = a @ a.T
# brute force approach
brute = []
for x in list0:
brute.append([np.dot(x, y) for y in list0])
brute = np.array(brute)
print((brute == result).all())
输出
True
注意:该代码已在Python 3.5中运行
答案 1 :(得分:0)
您可以坚持使用numpy
import numpy as np
import random
vals = []
num_vecs = 3
dimension = 4
for n in range(num_vecs):
val = []
for _ in range(dimension):
val.append(random.random())
vals.append(val)
# make into numpy array
vals = np.stack(vals)
print(vals.shape == (num_vecs, dimension))
# multiply every vector with every other using broadcastin
every_with_every_mult = vals[:, None] * vals[None, :]
print(every_with_every_mult.shape == (num_vecs, num_vecs, dimension))
# sum the final dimension
every_with_every_dot = np.sum(every_with_every_mult, axis=every_with_every_mult.ndim - 1)
print(every_with_every_dot.shape == (num_vecs, num_vecs))
# check it works
for i in range(num_vecs):
for j in range(num_vecs):
assert every_with_every_dot[i,j] == np.sum(vals[i]*vals[j])