方法#1
这是一种 NumPy 方法,通过这些成对的索引组合创建网格 -
# Create input array from those vectors
a = np.array([A,B,C])
n = len(a)
# Create grid of indices
r,c = np.mgrid[:n,:n]
# Index for final output
out = a[np.c_[c.ravel().T,r.ravel()]]
样本输入、输出-
In [365]: A = [1,0,0]
...: B = [0,1,0]
...: C = [0,0,1]
In [367]: out
Out[367]:
array([[[1, 0, 0],
[1, 0, 0]],
[[0, 1, 0],
[1, 0, 0]],
[[0, 0, 1],
[1, 0, 0]],
[[1, 0, 0],
[0, 1, 0]],
[[0, 1, 0],
[0, 1, 0]],
[[0, 0, 1],
[0, 1, 0]],
[[1, 0, 0],
[0, 0, 1]],
[[0, 1, 0],
[0, 0, 1]],
[[0, 0, 1],
[0, 0, 1]]])
方法 #2(针对性能)
我们可以利用输入是 one-hot 向量这一事实来获得性能,特别是对于具有更大长度的大量向量,通过初始化输出数组并将其分配给它。使用 one-hotness 的诀窍是使用 argmax 获取每个向量的单值唯一索引。我们将使用这些索引仅在那些特定位置分配到输出。实施将是 -
def multidim_hotvectors(a): # a is input list of vectors = [A,B,C]
n = len(a)
idx = np.array([np.argmax(i) for i in a])
putval = (idx[:,None] == np.arange(n)).astype(int)
out = np.zeros((n,n,2,n),dtype=int)
out[:,:,0,:] = putval[:,None,:]
out[:,:,1,:] = putval
out.shape = (n**2,2,-1)
return out
运行时测试
a = [A,B,C] 的其他方法 -
# @Engineero's soln
np.array([c for c in itertools.product(a, repeat=2)])
# @B. M.'s soln
np.array(list(itertools.product(a,a)))
设置单热向量输入列表的功能 -
def create_input_list_vectors(L):
d = (np.random.choice(L,L,replace=0)[:,None] == range(L)).astype(int)
return list(map(list,d))
时间安排 -
In [359]: a = create_input_list_vectors(L=5)
In [360]: %timeit np.array([c for c in itertools.product(a, repeat=2)])
...: %timeit np.array(list(itertools.product(a,a)))
...: %timeit multidim_hotvectors(a)
10000 loops, best of 3: 29.4 µs per loop
10000 loops, best of 3: 27.8 µs per loop
10000 loops, best of 3: 30.5 µs per loop
In [361]: a = create_input_list_vectors(L=20)
In [362]: %timeit np.array([c for c in itertools.product(a, repeat=2)])
...: %timeit np.array(list(itertools.product(a,a)))
...: %timeit multidim_hotvectors(a)
1000 loops, best of 3: 966 µs per loop
1000 loops, best of 3: 967 µs per loop
10000 loops, best of 3: 125 µs per loop
In [363]: a = create_input_list_vectors(L=100)
In [364]: %timeit np.array([c for c in itertools.product(a, repeat=2)])
...: %timeit np.array(list(itertools.product(a,a)))
...: %timeit multidim_hotvectors(a)
10 loops, best of 3: 98.6 ms per loop
10 loops, best of 3: 98.1 ms per loop
100 loops, best of 3: 3.94 ms per loop