【问题标题】:Fast expansion of category values to rows of normalised feature vector in a matrix将类别值快速扩展为矩阵中的归一化特征向量行
【发布时间】:2014-10-26 22:37:00
【问题描述】:

我正在寻找一种有效的矢量化方法,将类别编号的列向量扩展为标准化特征矩阵。

例如,我可能有:

octave:16> false_vals
false_vals =

  -0.10000  -0.20000  -0.50000

octave:17> true_vals
true_vals =

   0.90000   0.80000   0.50000

octave:18> cats
cats =

   1
   2
   3

我想将它们组合起来创建一个矩阵,其中每一行与false_vals 相同,但由cats 标识的索引位置设置为true_vals 中的相应值。例如,它看起来像这样:

octave:19> X
X =

   0.90000  -0.20000  -0.50000
  -0.10000   0.80000  -0.50000
  -0.10000  -0.20000   0.50000

我发现this question and answer 可以扩展给我一个随机分配:

octave:28> X = repmat(false_vals,3,1)
X =

  -0.10000  -0.20000  -0.50000
  -0.10000  -0.20000  -0.50000
  -0.10000  -0.20000  -0.50000

octave:29> Y = repmat(true_vals,3,1)
Y =

   0.90000   0.80000   0.50000
   0.90000   0.80000   0.50000
   0.90000   0.80000   0.50000

octave:30> L = ( rand(3,3) > 0.5 ) % This stands in for the actual logical matrix I want
L =

   1   1   1
   1   1   1
   0   0   1

octave:31> X(L) = Y(L)
X =

   0.90000   0.80000   0.50000
   0.90000   0.80000   0.50000
  -0.10000  -0.20000   0.50000

但我随后被困在如何用一些可以将我的cats 向量转换为的函数替换上面的rand

L = 
 1  0  0
 0  1  0
 0  0  1

即我知道我可以用逻辑矩阵做我想做的事,但不知道如何从我的向量cats 到正确的逻辑矩阵(对于L 的每一行,列位置由该行的值标识cats 向量应该是真的,所以我可以在最后一个语句中使用它。

【问题讨论】:

    标签: matlab matrix octave categorical-data


    【解决方案1】:

    您可以使用repmat 重复该行,然后使用linear indexing 替换所需的值:

    n = numel(cats);
    result = repmat(false_vals, n, 1); %// repeat row n times
    result((cats.'-1)*n+(1:n)) = true_vals; %'// replace desired values
    

    【讨论】:

    • 这适用于 L 的陈述,但我认为 OP 的一般情况要求是基于 rand 的解决方案。 +1 是一个好的起点!
    • 好的,明白了,线性索引是行优先的,这让我很困惑。
    【解决方案2】:

    代码

    N = 3; %// size of false_vals and true_vals
    
    %// Expand false_vals to create X
    X = repmat(false_vals,N,1)
    
    %// Find linear indices for expanded matrix, where true_vals are to be put
    %// For this, you would need two things - row and column indices.
    %// 1. Row indices would be just [1:N], as we are looking to get one replacement
    %// per row.
    %// 2. Column indices would be either of 1 or 2 or .. N
    ind = round((N-1)*rand(1,N)) %// ind would be column indices minus 1
    true_vals_idx = N*ind+[1:N] %// [1:N] represent the row indices
    
    %// Replace the elements at those linearly indexed positions with true_vals 
    X(true_vals_idx) = true_vals
    

    如果除了之前每行一个替换的标准,您还希望每列有一个替换,您可以修改ind 计算部分,有点像这样 -

    %// Create unique numbers for the interval [1,N], which could also be calculated with 
    %// randperm, but that being slow has been replaced by a sort-based implementation
    [~,ind] = sort(rand(N,1)) 
    true_vals_idx = N*(ind-1)+[1:N]
    
    %// .. Rest of the code stays the same
    

    注意:“重新创建”randperm 的基于排序的实现是基于this solution

    【讨论】:

    • 这很有用,包括我需要的答案,但我可能通过提及rand() 使事情变得更复杂。我在我的问题中使用它来代表“我知道我在这里需要一个逻辑矩阵,但不知道如何从cats 创建正确的矩阵” - 我将编辑并尝试更清楚。
    • @NeilSlater 如果是这样的话,Luis 的解决方案一定是最有效的。
    猜你喜欢
    • 2014-10-30
    • 2011-09-29
    • 2015-11-03
    • 2019-04-27
    • 2012-08-08
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多