【问题标题】:3 Dimensional Combination of One-hot VectorsOne-hot 向量的 3 维组合
【发布时间】:2018-04-15 06:41:39
【问题描述】:

我需要在 python 中创建一个包含所有 3x1 one-hot 向量对的 3 维列表,但我无法生成数组。我正在尝试使用np.arange 来做这件事,但我还没有完全做到这一点。例如,我的 one-hot 向量是: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数组,由one-hot向量对的所有组合组成。

【问题讨论】:

    标签: python numpy one-hot-encoding


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您可以使用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])]
      

      【讨论】:

        【解决方案3】:

        你可以用 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) 
        

        【讨论】:

        • 如果我使用通用集,比如:A = [0,1,0] ; B = [1,0,0]; C = [0,0,1],第二个的输出似乎与预期的不同。再检查一遍?
        【解决方案4】:

        由于我对 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']]
        

        注意打印结果中的换行符是为了让它适合屏幕

        【讨论】:

          猜你喜欢
          • 2019-08-28
          • 2017-09-19
          • 1970-01-01
          • 1970-01-01
          • 2017-06-07
          • 1970-01-01
          • 1970-01-01
          • 2020-10-10
          • 1970-01-01
          相关资源
          最近更新 更多