检查单元格内的成员

时间:2014-01-28 17:28:27

标签: matlab compare cell

我有一个像这样的单元格数组(data)(此处缩写):

'45.203885' '-90.600123'    '119-8001'  733144  NaN
'45.203885' '-90.600123'    '119-8001'  733147  NaN
'45.203885' '-90.600123'    '119-8001'  733150  NaN
'45.203885' '-90.600123'    '119-8001'  733153  NaN
'45.203885' '-90.600123'    '119-8001'  733156  NaN
'45.203885' '-90.600123'    '119-8001'  733159  NaN

我想填写NaN的第5列,具体取决于第4列(使用datenum转换的日期)是否与B匹配。

B(也是一个单元格)看起来像这样(为了有意义的例子也缩短了很多):

'45.203885' '-90.600123'    '119-8001'  733144  '3.3'
'45.203885' '-90.600123'    '119-8001'  733150  '9.5'
'45.203885' '-90.600123'    '119-8001'  733156  '6.8'

如您所见,第4列日期并未在B中持续前进。我正在尝试将NaN添加到第5列,其中B(:,3)B(:, 4)data(:,3)data(:, 4)不匹配。

最终产品应该类似于:

'45.203885' '-90.600123'    '119-8001'  733144  '3.3'
'45.203885' '-90.600123'    '119-8001'  733147  NaN
'45.203885' '-90.600123'    '119-8001'  733150  '9.5'
'45.203885' '-90.600123'    '119-8001'  733153  NaN
'45.203885' '-90.600123'    '119-8001'  733156  '6.8'
'45.203885' '-90.600123'    '119-8001'  733159  NaN

如果data是矩阵,我只会执行以下操作:

data_ind = ismember(data(:,3:4),B(:,3:4),'rows');

但我不知道如何用细胞做到这一点。某种形式的cellfun可以解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

sd = size(data,1); %// number of rows of data
sb = size(B,1); %// number of rows of B
[dd bb] = ndgrid(1:sd,1:sb); %// all combinations (row of data, row of B)
cond1 = strcmp(data(dd,3),B(bb,3)); %// test col 3 for all combinations
cond2 = [data{dd,4}].'==[B{bb,4}].'; %// test col 4 for all combinations
cond = reshape(cond1 & cond2, sd, sb); %// combine the two conditions
[ib, id] = max(cond); %// id contains the index of the first 1 (if any) ...
%// ... of each col in cond; and ib is a logical index of the row of that 1
id = id(ib); %// keep only id for which the maximum is 1
data(id,:) = B(ib,:); %// copy matching rows of B into data

dataB包含与其他变量的任何行都不匹配的行的示例:

data = {
    '45.203885' '-90.600123'    '119-8001'  733144  NaN
    '45.203885' '-90.600123'    '119-8001'  733147  NaN
    '45.203885' '-90.600123'    '119-8001'  733150  NaN
    '45.203885' '-90.600123'    '119-8001'  733153  NaN
    '45.203885' '-90.600123'    '119-8001'  733156  NaN
    '45.203885' '-90.600123'    '119-8001'  733159  NaN};

B = {
    '45.203885'    '-90.600123'    '119-8001'    [733144]    '3.3'
    '45.203885'    '-90.600123'    '119-8001'    [733150]    '9.5'
    '45.203885'    '-90.600123'    '119-8001'    [733156]    '6.8'
    '45.203885'    '-90.600123'    '169-8001'    [833156]    '6.8'};

结果:

data = 

    '45.203885'    '-90.600123'    '119-8001'    [733144]    '3.3'
    '45.203885'    '-90.600123'    '119-8001'    [733147]    [NaN]
    '45.203885'    '-90.600123'    '119-8001'    [733150]    '9.5'
    '45.203885'    '-90.600123'    '119-8001'    [733153]    [NaN]
    '45.203885'    '-90.600123'    '119-8001'    [733156]    '6.8'
    '45.203885'    '-90.600123'    '119-8001'    [733159]    [NaN]

答案 1 :(得分:2)

由于您将只拥有唯一的ID + datenum组合,因此您可以执行以下操作:

data_ind = ismember(strcat(data(:,3),num2str([data{:,4}]')),...
                    strcat(B(:,3),num2str([B{:,4}]')));

这样做是将第3列和第4列连接成单个字符串,例如

'45.203885' '-90.600123'    '119-8001'  733144  NaN
'45.203885' '-90.600123'    '119-8001'  733147  NaN

会变成

'119-8001733144'
'119-8001733147'

等等。然后,它会将data矩阵中的这些字符串与B矩阵进行比较,为您提供索引矩阵。

答案 2 :(得分:2)

目前还不清楚你在第三栏做了什么,因为所有参赛作品都是相同的。此外,如果您想要B中的datadata中的B,您的问题会有点令人困惑。可能最快,最直接的方法是使用for循环:

data = {'45.203885' '-90.600123'    '119-8001'  733144  NaN
        '45.203885' '-90.600123'    '119-8001'  733147  NaN
        '45.203885' '-90.600123'    '119-8001'  733150  NaN
        '45.203885' '-90.600123'    '119-8001'  733153  NaN
        '45.203885' '-90.600123'    '119-8001'  733156  NaN
        '45.203885' '-90.600123'    '119-8001'  733159  NaN};

B = {'45.203885' '-90.600123'    '119-8001'  733144  '3.3'
     '45.203885' '-90.600123'    '119-8001'  733150  '9.5'
     '45.203885' '-90.600123'    '119-8001'  733156  '6.8'};

d3 = data(:,3);
d4 = [data{:,4}].';
for i = 1:size(B,1)
    data(strcmp(d3,B{i,3})&d4==B{i,4},5) = B(i,5);
end

不要害怕使用for循环。您也可以使用cellfun执行此操作,但需要使用eval