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)),:);
因为您也可以使用,但是
>> 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
因为您也可以使用,但是
>> 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命令吗