首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择与另一个单元格数组内容匹配的单元格数组的索引。

选择与另一个单元格数组内容匹配的单元格数组的索引。
EN

Code Review用户
提问于 2017-03-18 08:55:21
回答 2查看 64关注 0票数 4

我有一个Matlab结构,有几个字段,其中3个在这里很有趣:

代码语言:javascript
复制
elec.label %Nx1 cell-array of strings
elec.chanpos %Nx3 matrix of doubles
elec.elecpos %Nx3 matrix of doubles

标签包含通道的唯一名称,而chanposelecpos包含坐标,其方式是elec.label(1)具有通道1的名称,elec.chanpos(1,:)elec.elecpos(1,:)具有通道1的坐标。

我需要的是创建一个类似的结构,它是elec的一个子集,包含标签和两个坐标字段,并且基于我所拥有的标签列表。我所拥有的标签不一定与elec.label数组中使用的大写字母匹配。

我是如何实现这个的:

代码语言:javascript
复制
list46={'fpz';'afz';};%Real list is really long, so I truncated it.
INDX46=[];
for i=1:length(elec.label)
    for j=1:length(list46)
        if(strcmpi(list46(j),elec.label(i)))
            INDX46=[INDX46; i;];
        end
    end
end

elec46.chanpos=elec.chanpos(INDX46,:);
elec46.elecpos=elec.elecpos(INDX46,:);
elec46.label=elec.label(INDX46,:);

我所做的实现,对我来说,感觉就像是在用Matlab编程C。我正在寻找一种更有效的,或至少更多的马塔巴斯克的方式来做到这一点。

EN

回答 2

Code Review用户

回答已采纳

发布于 2019-05-28 18:57:25

附加到数组

INDX46=[INDX46; i;];是附加到向量的一种非常慢的方式。相反,请执行INDX46(end+1) = i;

当以这种首选的方式附加到矩阵时,MATLAB实际上扩展了向量的存储。MATLAB将使底层内存块的大小加倍,以便重复添加将是最优的(O(log )而不是O( n) )。也就是说,大多数循环迭代--数据不需要复制--就可以扩展数组。

相反,第一种追加方法实际上创建了一个新数组,并将旧数组和新值复制到其中。解释器不使用扩展数组的最优O(log )方法。

有关演示上述内容的实验,请参见关于堆栈溢出的问答

查找字符串

OP中没有任何数据可以很容易地用于测试修改,但在我看来,双循环是比较list46的每个元素和elec.label的每个元素,以便在后者中找到包含前者的一个元素的索引。通过将两个列表按字母顺序排序,可以大大加快这个循环的速度。对于两个排序的列表,一个只需要遍历两个列表一次就可以找到所有的匹配。该算法从O(nm)到O(n+m),两个阵列的长度分别为n和m。

MATLAB有一个函数ismember,它就是这样做的:

代码语言:javascript
复制
INDX46 = ismember(elec.label, list46);
票数 2
EN

Code Review用户

发布于 2017-04-19 20:54:53

下面的向量化表单可以替换您的双循环:

代码语言:javascript
复制
INDX46 = sort(cell2mat(cellfun(@(x)find(strcmp(x,elec.label)),list46,'UniformOutput',false)))'

(如果INDX46的顺序无关紧要,则可以删除sort函数)。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/158110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档