单热矢量的三维组合

时间:2017-11-02 16:40:44

标签: python numpy one-hot-encoding

我需要在python中创建所有3x1单热矢量对的三维列表,但是我在生成数组时遇到了麻烦。我正在尝试使用np.arange来完成它,但我还没有完全实现这一点。例如,我的单热矢量是:A=[1,0,0] B=[0,1,0] and C=[0,0,1]。我需要的输出是三维数组[[A,A],[A,B],[A,C],[B,A],[B,B],[B,C],[C,A],[C,B],[C,C]]即9x2x3数组,包含一对热矢量的所有组合。

4 个答案:

答案 0 :(得分:2)

方法#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-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

答案 1 :(得分:0)

您可以使用itertools.product执行此操作:

import itertools as it
combos = [c for c in it.product([A, B, C], repeat=2)]
# combos = [([1, 0, 0], [1, 0, 0]),
#           ([1, 0, 0], [0, 1, 0]),
#           ([1, 0, 0], [0, 0, 1]),
#           ([0, 1, 0], [1, 0, 0]),
#           ([0, 1, 0], [0, 1, 0]),
#           ([0, 1, 0], [0, 0, 1]),
#           ([0, 0, 1], [1, 0, 0]),
#           ([0, 0, 1], [0, 1, 0]),
#           ([0, 0, 1], [0, 0, 1])]

答案 2 :(得分:0)

由于我不熟悉numpy,因此这是一个单行/双线解决方案。

为方便起见,我们将A='a'B='b'C='c'

鉴于你所有的'热矢量'(不确定它们是什么,但无论如何)存储在一个矢量中:

>>> options = [A,B,C]
>>> result = [x,y for x in options for y in options]
>>> print(result)
[['a', 'a'], ['b', 'a'], ['c', 'a'],
 ['a', 'b'], ['b', 'b'], ['c', 'b'],
 ['a', 'c'], ['b', 'c'], ['c', 'c']]

请注意,打印结果中的换行符是为了使其适合屏幕

答案 3 :(得分:0)

您可以使用itertools:

A,B,C=np.eye(3,dtype=int)
import itertools 
l=list(itertools.product((A,B,C),(A,B,C)))
a923=np.array(l)

或直接在numpy:

points=np.array([
[1,0,0],
[0,1,0],
[0,0,1]])
n,dim=points.shape
indices=np.indices((n,n))

# indice.T :
# array([[[0, 0],
#         [1, 0],
#         [2, 0]],
# 
#        [[0, 1],
#         [1, 1],
#         [2, 1]],
# 
#        [[0, 2],
#         [1, 2],
#         [2, 2]]])

res = points[indices.T].reshape(n*n,2,dim)