我有一个由元组的所有组合组成的列表,每个元素只能是 -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(对)+ 4(本身)= 10 个组合;
对于 N=3
将有 28(对)+ 8(本身)= 36 种组合。
对于小的N
我可以做类似的事情:
for x in list0:
for y in list0:
print(np.dot(x,y))
但是,假设我已经有了 list0,如果 N 很大,例如 ~50,计算点积的所有可能性的最佳方法是什么?
最佳答案
您可以使用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
您要问的是 a
与其自身的矩阵乘法,来自 documentation :
if both a and b are 2-D arrays, it is matrix multiplication,
请注意,最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 中运行
关于计算列表内成对点积的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52997236/