Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.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 vs isequal_Matlab_Matlab Table - Fatal编程技术网

MATLAB:ismember vs isequal

MATLAB:ismember vs isequal,matlab,matlab-table,Matlab,Matlab Table,如果A和B是具有相同列(且顺序相同)的表(或数据集),则类似ismember(A(:,somecols),B(:,somecols))的表达式将生成一个适用于索引A的布尔数组,如中所示 A(ismember(A(:, somecols), B(:, somecols)), :) 上面的行计算为一个表(或数据集,具体取决于a)的类别,该表由a的行组成,这些行与B的某一行在somecols中指定的列相匹配 但是现在假设B正好有一行。更现实地说,假设从A中选择行的标准只是匹配B的这一行,比如第一行

如果
A
B
是具有相同列(且顺序相同)的表(或数据集),则类似
ismember(A(:,somecols),B(:,somecols))
的表达式将生成一个适用于索引
A
的布尔数组,如中所示

A(ismember(A(:, somecols), B(:, somecols)), :)
上面的行计算为一个
(或
数据集
,具体取决于
a
)的类别,该表由
a
的行组成,这些行与
B
的某一行在
somecols
中指定的列相匹配

但是现在假设
B
正好有一行。更现实地说,假设从
A
中选择行的标准只是匹配
B
的这一行,比如第一行

我们可以这样做:

A(ismember(A(:, somecols), B(1, somecols)), :)
我对此的主要质疑是,它不是“语义清晰的”,因为实际上,
ismember
正被用来测试平等性

如果一个人能写,在语义上会更清楚

A(isequal(A(:, somecols), B(1, somecols)), :)
但这条线并没有产生预期的结果。(特别是,即使
A(:,…)
包含匹配
B(1,…)
的行,它也不会返回匹配项)


我的问题是,什么谓词能够正确地生成与问题“这一行
A
是否与
somecols
处的这一参考行匹配?”相对应的逻辑向量?

我同意,使用
ismember
选项可能无法立即清楚您的意图(虽然它没有什么问题)。另一种方法是使用
bsxfun
,我想它在语义上可能更清晰(尽管可能效率更低):

all(bsxfun(@eq,A(:,somecols),B(1,somecols)),2);
如果你把它扩展到引擎盖下发生的事情,它会是这样的:

a = A(:,somecols);
b = repmat(B(1,somecols),size(A,1),1);
abeq = all(a == b,2);
A(abeq,:);
基本上,您要复制一个
B
行,使其与
A(:,somecols)
大小相同,然后比较每个数组中的每个值。最后,您要检查哪些行有一整行
true
(使用
all
),这表明它与单个B行匹配

编辑:抱歉,显然我误解了这个问题-如果您使用的是
数据类型(我直到几分钟前才知道它的存在-谢谢horchler),那么这种方法可能不起作用

EDIT2:不象指出存在作用于表中每一行的函数
rowfun
。我无法测试这一点(我的MATLAB版本不够新),但我假设这样的函数可以满足您的需要:

A(rowfun(@(x) isequal(B(1,somecols),x),A(:,somecols)),:);

我同意使用
ismember
选项可能无法立即明确您的意图(尽管它没有什么问题)。另一种方法是使用
bsxfun
,我想在语义上更清晰(尽管可能效率更低),如下所示:

all(bsxfun(@eq,A(:,somecols),B(1,somecols)),2);
如果你把它扩展到引擎盖下发生的事情,它会是这样的:

a = A(:,somecols);
b = repmat(B(1,somecols),size(A,1),1);
abeq = all(a == b,2);
A(abeq,:);
基本上,您要复制一个
B
行,使其与
A(:,somecols)
大小相同,然后比较每个数组中的每个值。最后,您要检查哪些行有一整行
true
(使用
all
),这表明它与单个B行匹配

编辑:抱歉,显然我误解了这个问题-如果您使用的是
数据类型(我直到几分钟前才知道它的存在-谢谢horchler),那么这种方法可能不起作用

EDIT2:不象指出存在作用于表中每一行的函数
rowfun
。我无法测试这一点(我的MATLAB版本不够新),但我假设这样的函数可以满足您的需要:

A(rowfun(@(x) isequal(B(1,somecols),x),A(:,somecols)),:);

因为您也可以使用,但是 IsSudio在这种情况下是相当清楚的。请考虑< <代码>表>代码> s代码> 和<代码> BT<代码>,其中代码> BT有两个公共行和一个唯一行:

>> A = randi(7,4,5);
>> commonRows = [1 3];
>> B = [A(commonRows,:); randi(2,1,5)+7];
>> At = array2table(A,'VariableNames',sprintfc('C%d',1:size(A,2)))
At = 
    C1    C2    C3    C4    C5
    __    __    __    __    __
    4     1     5     7     7 
    2     6     5     1     4 
    4     4     6     7     4 
    2     7     7     5     6 
>> Bt = array2table(B,'VariableNames',sprintfc('C%d',1:size(A,2)))
Bt = 
    C1    C2    C3    C4    C5
    __    __    __    __    __
    4     1     5     7     7 
    4     4     6     7     4 
    8     8     9     9     9 

第二个输出参数:<代码>内部连接< /代码>,代码> IA < /代码>,给出了<<代码> A/<代码>中的行的索引,也在<代码> b/COD>中。如在示例中,考虑列的子集,由“代码> > SoCeOLSO:

>> somecols = [2 5]
somecols =
     2     5
>> [Ct,IA] = innerjoin(At(:,somecols), Bt(1,somecols))
Ct = 
    C2    C5
    __    __
    1     7 
IA =
     1
>> [Ct,IA] = innerjoin(At(:,somecols), Bt(2,somecols))
Ct = 
    C2    C5
    __    __
    4     4 
IA =
     3
>> [Ct,IA] = innerjoin(At(:,somecols), Bt(3,somecols))
Ct = 
   empty 0-by-2 table
IA =
     []
如果
IA
为空(或非空),则应进行以下测试:

>> [~,IA] = innerjoin(At, Bt(3,:));
>> isempty(IA)
ans =
     1
>> [~,IA] = innerjoin(At, Bt(2,:));
>> isempty(IA)
ans =
     0
或者只测试第一个输出,即公共表行:

>> isempty(innerjoin(At, Bt(3,:)))
ans =
     1
>> isempty(innerjoin(At, Bt(1,:)))
ans =
     0

因为您也可以使用,但是 IsSudio在这种情况下是相当清楚的。请考虑< <代码>表>代码> s代码> 和<代码> BT<代码>,其中代码> BT有两个公共行和一个唯一行:

>> A = randi(7,4,5);
>> commonRows = [1 3];
>> B = [A(commonRows,:); randi(2,1,5)+7];
>> At = array2table(A,'VariableNames',sprintfc('C%d',1:size(A,2)))
At = 
    C1    C2    C3    C4    C5
    __    __    __    __    __
    4     1     5     7     7 
    2     6     5     1     4 
    4     4     6     7     4 
    2     7     7     5     6 
>> Bt = array2table(B,'VariableNames',sprintfc('C%d',1:size(A,2)))
Bt = 
    C1    C2    C3    C4    C5
    __    __    __    __    __
    4     1     5     7     7 
    4     4     6     7     4 
    8     8     9     9     9 

第二个输出参数:<代码>内部连接< /代码>,代码> IA < /代码>,给出了<<代码> A/<代码>中的行的索引,也在<代码> b/COD>中。如在示例中,考虑列的子集,由“代码> > SoCeOLSO:

>> somecols = [2 5]
somecols =
     2     5
>> [Ct,IA] = innerjoin(At(:,somecols), Bt(1,somecols))
Ct = 
    C2    C5
    __    __
    1     7 
IA =
     1
>> [Ct,IA] = innerjoin(At(:,somecols), Bt(2,somecols))
Ct = 
    C2    C5
    __    __
    4     4 
IA =
     3
>> [Ct,IA] = innerjoin(At(:,somecols), Bt(3,somecols))
Ct = 
   empty 0-by-2 table
IA =
     []
如果
IA
为空(或非空),则应进行以下测试:

>> [~,IA] = innerjoin(At, Bt(3,:));
>> isempty(IA)
ans =
     1
>> [~,IA] = innerjoin(At, Bt(2,:));
>> isempty(IA)
ans =
     0
或者只测试第一个输出,即公共表行:

>> isempty(innerjoin(At, Bt(3,:)))
ans =
     1
>> isempty(innerjoin(At, Bt(1,:)))
ans =
     0

仅供参考,
bsxfun
eq
没有为
数据类型定义,不幸的是,如果不转换为另一种格式,两个代码片段都无法工作(这并不总是可能的).table是一个新的MATLAB命令吗?我仍然在运行R2012a,对我来说它似乎不存在。我想是的。我以为有以前的东西,但我找不到。在统计工具箱中有。Tables似乎也带来了聚会,因为它的语义稍微更清晰sapproach@Notlikethat:很好的发现!还有。列出了所有
table
方法/属性。仅供参考,
bsxfun
eq
没有为
table
数据类型定义,不幸的是,如果不转换为另一种格式,两个代码段都无法工作(这并不总是可能的)
table
是一个新的MATLAB命令吗