【问题标题】:Generalized element-wise array replication (each element replicated by a variable size) in MATLAB [duplicate]MATLAB中的广义元素数组复制(每个元素以可变大小复制)[重复]
【发布时间】:2013-04-04 08:04:12
【问题描述】:

这里有一个类似的问题,Element-wise array replication in Matlab,但我想稍微概括一下。简单的情况需要一个“复制”函数,该函数将采用一个向量 a,然后将每个元素复制一个数字 N。例如

>> a = [1, 2, 3];
>> replicate(a, 3);
ans = 
  [1, 1, 1, 2, 2, 2, 3, 3, 3]
>>

以上链接中有许多有用的解决方案。但是,N 是每个元素的多重性向量会发生什么?例如,我想要类似的东西:

>> a = [1, 2, 3];
>> N = [3, 1, 5];
>> replicate(a,N)
ans = 
  [1, 1, 1, 2, 3, 3, 3, 3, 3]
>>

不幸的是,我的 MATLAB-index-fu 还没有达到这个水平,如果不循环遍历 N,然后使用 repmat 将 a 的每个元素平铺到 a 中,我无法弄清楚如何做到这一点大小 [N(i),1] 向量。例如。我在数组数据上循环,然后使用 multcol 位置的多重性值对其进行repmat。数据是 MCMC 中的步骤,每个步骤的多重性在最后一列。

data=[-3.997 4.402 0.000 703.050 -219.900 289.600 2.000 5.700 -49.100 11.100 3;...
-2.476 2.685 0.000 667.800 -220.210 290.000 1.955 5.710 -48.828 11.116 3; ...
-4.658 0.286 0.000 626.370 -220.420 290.380 2.019 5.991 -49.015 11.1210 2];

multcol = 11;

%unwrap the data
in=1;
for i=1:size(data,1)
  data_uw(in:in+data(i,multcol)-1,:) = ...
    repmat(data(i,1:multcol-1),[data(i,multcol) 1]);
  in=in+data(i,multcol);
end

这可行,但相对较慢。最终结果data_uw是输入矩阵的每一行,data,在multiplicity列中被复制的次数。

>> data_uw

data_uw =

Columns 1 through 7

-3.9970    4.4020         0  703.0500 -219.9000  289.6000    2.0000
-3.9970    4.4020         0  703.0500 -219.9000  289.6000    2.0000
-3.9970    4.4020         0  703.0500 -219.9000  289.6000    2.0000
-2.4760    2.6850         0  667.8000 -220.2100  290.0000    1.9550
-2.4760    2.6850         0  667.8000 -220.2100  290.0000    1.9550
-2.4760    2.6850         0  667.8000 -220.2100  290.0000    1.9550
-4.6580    0.2860         0  626.3700 -220.4200  290.3800    2.0190
-4.6580    0.2860         0  626.3700 -220.4200  290.3800    2.0190

Columns 8 through 10

  5.7000  -49.1000   11.1000
  5.7000  -49.1000   11.1000
  5.7000  -49.1000   11.1000
  5.7100  -48.8280   11.1160
  5.7100  -48.8280   11.1160
  5.7100  -48.8280   11.1160
  5.9910  -49.0150   11.1210
  5.9910  -49.0150   11.1210

有没有更好的方法来做到这一点?也许有一种方法可以调整上面链接中的答案,但我不明白。

更新答案

我使用了http://www.mathworks.co.uk/matlabcentral/fileexchange/6436-rude-a-pedestrian-run-length-decoder-encoder 提供的实用程序粗鲁。

mult = data(:,multcol);
data = data(:,1:multcol-1);
iterations = sum(mult);

%preallocate the unwrapped data vector for speed
data_uw = zeros(iterations,multcol-1);
nstep = size(data,1);
ind = 1:nstep;
ind_uw = zeros(iterations,1);
ind_uw = rude(mult,ind);
data_uw = data(ind_uw,:);

这似乎要快得多。粗鲁利用了另一个答案中提到的 cumsum 技术,所以这也可以。

【问题讨论】:

  • 你能让最后一个块可执行吗? (datamultcol 的虚拟初始化)。目前尚不完全清楚所需的输出是什么。
  • 是的,它看起来绝对像个骗子。抱歉,我在找的时候没找到。射击。现在我看到它链接在我链接到的问题的侧栏中。

标签: matlab indexing reshape


【解决方案1】:

您可以对这种事情使用基于 cumsum 的索引:

A = [4 5 6];
N = [3 1 5];

cs=cumsum(N);
idx = zeros(1,cs(end));
idx(1+[0 cs(1:end-1)]) = 1; #%[1 0 0 1 1 0 0 0 0]
idx = cumsum(idx); #%[1 1 1 2 3 3 3 3 3]

B = A(idx); #%[4 4 4 5 6 6 6 6 6]

【讨论】:

  • 哦,很好。非常聪明!感谢您的 cumsum 提示。
【解决方案2】:

算法是游程解码,我建议使用rude()。这是一个里程碑,而且 MATLAB 代码写得很好。

>> rude(N,a)
ans =
     1     1     1     2     3     3     3     3     3

但是,在您的情况下,问题应该是预分配(缺少)。预分配和重构代码:

% Pre-allocate
out = zeros(sum(data(:,end)),multcol-1);

for i = 1:size(data,1)
    n = data(i,multcol);
    out(in : in+n-1,:) = repmat(data(i,1:end-1),n,1);
    in = in+n;
end

【讨论】:

  • 对不起,我去掉了示例中的预分配。我是在实际代码中这样做的。我已经改用粗鲁了,加速效果很好。仅从快速分析器运行来看,它似乎是 10-100 倍。不过,恐怕我还不能投票。
  • 理想情况下,可以将rude() 向量化以接受:矩阵、具有长度和维度参数的向量,以便复制行或列。
【解决方案3】:

简单的:

a = [1, 2, 3];
N = [3, 1, 5];

result = zeros(1,sum(N)); % mem alloc
k = 1;
for n = 1:numel(N)
        p = k+N(n)-1;
        result(1,k:p) = a(n);
        k = p+1;
end;

disp(result);

【讨论】:

    猜你喜欢
    • 2010-12-29
    • 2021-02-11
    • 1970-01-01
    • 2018-07-20
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    相关资源
    最近更新 更多