【问题标题】:Convert indices to vectors in Numpy在 Numpy 中将索引转换为向量
【发布时间】:2015-05-21 12:54:54
【问题描述】:

假设我们有这个数据:

import numpy as np
data = np.array([1,0,1,2,1,2])

我想把它转换成这个:

[0 1 0
 1 0 0
 0 1 0
 0 0 1
 0 1 0
 0 0 1]

如何在 Numpy(或其他相关包)中执行此操作?我们在 MATLAB 中有 ind2vec 函数来执行此操作。

【问题讨论】:

  • 这种转换背后的逻辑是什么?
  • 当我们有softmax函数作为输出层的传递函数用于分类目的时,这是用于神经网络的输出。
  • 输出与输入有什么关系?
  • 你的输入是[101]还是[1,0,1]
  • 请使用data 向量,而不是0s 和1s。这将使示例更容易理解。

标签: python matlab numpy


【解决方案1】:

在 NumPy 中执行此操作的一种相当常见的方法是将 dataarange 进行比较并将布尔数组转换为整数类型:

>>> (np.arange(3) == data[:,None]).astype(int)
array([[0, 1, 0],
       [1, 0, 0],
       [0, 1, 0],
       [0, 0, 1],
       [0, 1, 0],
       [0, 0, 1]])

更一般地说,如果你想指定N 列(类似于 Matlab 的函数),这里有一个包含必要步骤的函数。您可以将索引列表 ind 作为 Python 列表或 NumPy 数组传递:

def ind2vec(ind, N=None):
    ind = np.asarray(ind)
    if N is None: 
        N = ind.max() + 1
    return (np.arange(N) == ind[:,None]).astype(int)

那么例如:

>>> ind2vec([4,0,2])
array([[0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0]])

>>> ind2vec([1,3,2,1,0], N=10)
array([[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

【讨论】:

  • 真的很漂亮的答案:) (快速修复,不是ind.max()+1吗?)
  • @user2991243 你打算如何处理结果?也许您甚至不需要将其转换为 int。
【解决方案2】:

一种方法是:

import numpy as np
data = np.array([1,0,1,2,1,2])

idx = np.zeros((data.size, data.max()+1))
idx[np.arange(data.size), data] = 1

【讨论】:

  • 我会将range 替换为np.arange,行为相同,但对于大型N 更快。
  • @imaluengo 猜测取决于 python 版本... np.arange 将创建一个数组,其中 2.x 中的 xrange 和 3.x 中的 range 不会。
  • 我不知道 true 和 numpy 在多大程度上处理生成器而不事先将它们转换为列表。示例问题中的快速timeit(使用N = 6)已经表明np.arangexrange 快4 倍(在python 2.7 中,4.5us 用于使用xrange 进行索引,而1.2us 用于@987654332 @)。但这目前超出了当前问题的范围。
  • @imaluengo 从未尝试过,但显然你是对的......从我假设numpy 正在 将生成器变成数组的时间。但无论如何,ajcr 的答案更好:D
【解决方案3】:
def ind_to_vec(data):
    maxd = max(data)
    mind = min(data)
    b = np.zeros([len(data),maxd-mind+1])
    for ii in range(mind,maxd+1):
        for jj in range(len(data)):
            if data[jj]==ii:
                b[jj,ii]=1
    return b

这将遍历输入数组中的每个可能值,并检查它是什么值。然后,它会在对应于该值的列中填充一个 1,否则会被清零。输入数据的输出是

array([[ 0.,  1.,  0.],
[ 1.,  0.,  0.],
[ 0.,  1.,  0.],
[ 0.,  0.,  1.],
[ 0.,  1.,  0.],
[ 0.,  0.,  1.]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 2013-07-11
    • 2016-07-22
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    相关资源
    最近更新 更多