Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 检查单元格中的ismember_Matlab_Compare_Cell - Fatal编程技术网

Matlab 检查单元格中的ismember

Matlab 检查单元格中的ismember,matlab,compare,cell,Matlab,Compare,Cell,我有一个单元格数组(数据),看起来像这样(这里简称): 我想根据第四列(使用datenum转换的日期)是否与B匹配,填写NaN的第五列 B(也是一个单元格)看起来像这样(为了使示例更有意义,还缩短了很多): 如您所见,日期的第4列在B中并不一致。我试图将NaN添加到第5列,其中B(:,3)和B(:,4)与数据(:,3)和数据(:,4)不匹配 最终产品应类似于: '45.203885' '-90.600123' '119-8001' 733144 '3.3' '45.203885' '-

我有一个单元格数组(
数据
),看起来像这样(这里简称):

我想根据第四列(使用
datenum
转换的日期)是否与
B
匹配,填写
NaN
的第五列

B
(也是一个单元格)看起来像这样(为了使示例更有意义,还缩短了很多):

如您所见,日期的第4列在
B
中并不一致。我试图将
NaN
添加到第5列,其中
B(:,3)
B(:,4)
数据(:,3)
数据(:,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');
data_ind = ismember(strcat(data(:,3),num2str([data{:,4}]')),...
                    strcat(B(:,3),num2str([B{:,4}]')));
但我不知道怎么用手机。某种形式的
cellfun
会起作用吗

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
data
B
都包含与其他变量的任何行不匹配的行的示例:

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]

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

data_ind = ismember(data(:,3:4),B(:,3:4),'rows');
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'

等等。然后,它将这些字符串从
数据
矩阵与
B
矩阵进行比较,以给出索引矩阵。

由于所有条目都相同,因此不清楚您对第三列做了什么。另外,您的问题有点让人困惑,您想在
数据中使用
B
还是在
B
中使用
data
。可能最快、最直接的方法是使用
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

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

它表示
下标的赋值维度不匹配。
用于最后一行`数据(数据索引:)的大小为252x5。B的尺寸是190x5,因为它缺少日期。@shizishan我用一种新的方法重写了我的答案。我想现在它可以在一般情况下工作了。
strcmp(C1,C2)
syntax+
ndgrid
就是这里的问题。不需要
ismember
for
循环。聪明。@chappjc谢谢!有趣的是,在这种情况下,
max
的两个输出如何给出所需的两个索引(逻辑形式的列索引,数字形式的行索引)@chappjc:是的,但是可读性呢?(谁知道速度。)并且
ndgrid
对于
循环来说就像
arrayfun
cellfun
一样,同时使用更多内存。还有@LuisMendo:这个问题是被删除了一段时间还是什么?当@MrAzzaman和我发布我们的时间戳时,它并不在那里,但出于某种原因,时间戳要老得多。很好。如果第四列始终是整数,
int2str
可能会更好。如果这些值是十进制的,请注意默认情况下
num2str
仅使用“大约4位数字和一个指数(如果需要)”(
sprintf('.17g',…)
更安全)。第4列是datenum类型的数字,并且始终是整数,因为没有提供小时/分钟/秒数据。关于
int2str
,这一点很好,但是它不会有太大的区别-
num2str
如果输入是整数,则返回到
int2str
。是的,在检查数字是否为整数时会有一点开销,但从长远来看,这是可以忽略的。加上一个是为了可读性。虽然我很欣赏避免循环所需的技巧,但这并不意味着for循环有时不是最好的解决方案。