arrays - 在 MATLAB 中分割向量

标签 arrays matlab vector

我正在尝试优雅地拆分矢量。例如,

vec = [1 2 3 4 5 6 7 8 9 10]

根据另一个相同长度的 0 和 1 向量,其中 1 表示向量应该在何处拆分 - 或者更确切地说是剪切:

cut = [0 0 0 1 0 0 0 0 1 0]

为我们提供类似于以下内容的单元格输出:

[1 2 3] [5 6 7 8] [10]

最佳答案

解决方案代码

您可以使用 cumsum & accumarray一个有效的解决方案-

%// Create ID/labels for use with accumarray later on
id = cumsum(cut)+1   

%// Mask to get valid values from cut and vec corresponding to ones in cut
mask = cut==0        

%// Finally get the output with accumarray using masked IDs and vec values 
out = accumarray(id(mask).',vec(mask).',[],@(x) {x})

基准测试

以下是在列出的三种最流行的解决此问题的方法中使用大量输入时的一些性能数据 -

N = 100000;  %// Input Datasize

vec = randi(100,1,N); %// Random inputs
cut = randi(2,1,N)-1;

disp('-------------------- With CUMSUM + ACCUMARRAY')
tic
id = cumsum(cut)+1;
mask = cut==0;
out = accumarray(id(mask).',vec(mask).',[],@(x) {x});
toc

disp('-------------------- With FIND + ARRAYFUN')
tic
N = numel(vec);
ind = find(cut);
ind_before = [ind-1 N]; ind_before(ind_before < 1) = 1;
ind_after = [1 ind+1]; ind_after(ind_after > N) = N;
out = arrayfun(@(x,y) vec(x:y), ind_after, ind_before, 'uni', 0);
toc

disp('-------------------- With CUMSUM + ARRAYFUN')
tic
cutsum = cumsum(cut);
cutsum(cut == 1) = NaN;  %Don't include the cut indices themselves
sumvals = unique(cutsum);      % Find the values to use in indexing vec for the output
sumvals(isnan(sumvals)) = [];  %Remove NaN values from sumvals
output = arrayfun(@(val) vec(cutsum == val), sumvals, 'UniformOutput', 0);
toc

运行时

-------------------- With CUMSUM + ACCUMARRAY
Elapsed time is 0.068102 seconds.
-------------------- With FIND + ARRAYFUN
Elapsed time is 0.117953 seconds.
-------------------- With CUMSUM + ARRAYFUN
Elapsed time is 12.560973 seconds.

特殊情况:在您可能运行 1 的情况下,您需要修改下面列出的一些内容 -

%// Mask to get valid values from cut and vec corresponding to ones in cut
mask = cut==0  

%// Setup IDs differently this time. The idea is to have successive IDs.
id = cumsum(cut)+1
[~,~,id] = unique(id(mask))
      
%// Finally get the output with accumarray using masked IDs and vec values 
out = accumarray(id(:),vec(mask).',[],@(x) {x})

在这种情况下运行示例 -

>> vec
vec =
     1     2     3     4     5     6     7     8     9    10
>> cut
cut =
     1     0     0     1     1     0     0     0     1     0
>> celldisp(out)
out{1} =
     2
     3
out{2} =
     6
     7
     8
out{3} =
    10

关于arrays - 在 MATLAB 中分割向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29860008/

相关文章:

python - 使用 Python 的 Popen 类从 Django 调用 Matlab 脚本

java - 如何在不指向 Java 源列表中的对象的情况下复制 ArrayList?

c - 使用管道写入和读取 Int 数组

javascript - 从对象中提取单个键到数组

matlab - 神经网络优化与遗传算法

c++ - C++ vector 的 size() 和 capacity()

python - Numpy arange float 不一致

matlab - Otsu 方法(matlab 中的 graythresh 函数)在哪个尺度上产生缩放结果? 0 :255, 0 :max(px intensity), 分钟 :max?

c++ - 在 C++ 中存储和访问 N 维位数组中单个位的最快方法是什么?

rust - 如何编写一个转发到 vec 的可变 Rust 宏!宏?