【问题标题】:cell arrays manipulations in MATLAB --- creating a relation matrixMATLAB 中的元胞数组操作——创建关系矩阵
【发布时间】:2016-02-17 23:02:29
【问题描述】:

我有两个元胞数组,分别命名为countrynameexport

countryname中只有一列,是国家名称的代码:

USA  
CHN  
ABW

export中有两列:

USA ABW  
USA CHN  
CHN USA  
ABW USA  

export 一行中的每一对 (X,Y) 表示“国家 X 与国家 Y 有关系”。 countryname的大小已经被简化为3。在MATLAB中如何实现如下?

创建一个 3×3(通常是 n×n,其中 n 是 countryname 的大小)矩阵 M 使得

M(i,j)=1 如果国家 i 与国家 j 有关系
M(i,j)=0 否则。

国家名称在countryname 中被重新标记为正整数。

【问题讨论】:

  • @rayryeng:非常感谢您的编辑。
  • 没问题。祝你好运!

标签: arrays matlab matrix cell-array


【解决方案1】:

您需要做的第一件事是建立从国家名称到从 1 到 3 的整数值的映射。您可以使用 containers.Map 来做到这一点,其中输入是字符串,输出是整数。因此,我们将'USA' 分配给 1,'CHN' 分配给 2,'ABW' 分配给 3。假设您已经像上面提到的那样初始化了元胞数组:

countryname = {'USA', 'CHN', 'ABW'};
export = {'USA', 'ABW'; 'USA', 'CHN'; 'CHN', 'USA'; 'ABW', 'USA'};

...你会像这样创建一个containers.Map

map = containers.Map(countryname, 1:numel(countryname));

一旦你有了这个,你只需将国家名称映射到整数,你就可以使用values 函数来帮助你做到这一点。但是,将返回的是单个元素的元胞数组。我们需要解压元胞数组,因此您可以使用cell2mat。因此,我们现在可以创建一个4 x 2 索引矩阵,其中每个单元格元素都转换为一个数值:

ind = cell2mat(values(map, export));

因此我们得到:

>> ind

ind =

     1     3
     1     2
     2     1
     3     1

现在我们有了这个,您可以使用sparse 为您创建最终矩阵,其中第一列用作行位置,第二列用作列位置。这些位置将告诉您最终矩阵中的非零位置。但是,这将是一个稀疏矩阵,因此您需要将矩阵转换为 full 才能最终得到一个数值矩阵。

M = full(sparse(ind(:,1), ind(:,2), 1));

我们得到:

>> M

M =

     0     1     1
     1     0     0
     1     0     0

作为更方便的表示,您可以创建一个table 来显示最终矩阵。使用array2table 将矩阵M 转换为表格,我们可以将行名和列名添加为国家名称本身:

>> T = array2table(M, 'RowNames', countryname, 'VariableNames', countryname)

T = 

           USA    CHN    ABW
           ___    ___    ___

    USA    0      1      1  
    CHN    1      0      0  
    ABW    1      0      0 

请注意,上述创建table 的代码仅适用于 MATLAB R2013b 及更高版本。如果这不是您需要的,请坚持使用原始数字矩阵 M

【讨论】:

    【解决方案2】:

    这仅使用基本的 MATLAB 功能。 @rayryeng 上面发布的解决方案肯定要先进得多,并且编码速度也可能更快。但是,这也应该有助于您从基础层面理解

    clear
    country={'USA','CHN','ABW'};
    
    export={'USA' 'ABW'; 'USA' 'CHN'; 'CHN' 'USA' ; 'ABW' 'USA'};
    
    M=zeros(length(country));
    
    for i=1:length(country)
      c=country(i);
      ind_state=strfind(export(:,1),char(c));  % this gives state of every which is 1 or blank.
      ind_match=find(not(cellfun('isempty', ind_state))); % extracting only indices which are 1.
    
      exp_match=export(ind_match,2); % find corresponding export rel countries from second column
    
     % useful only when your first ind_match matrix has more than 1 element. 
     % Like 'USA' appears twice in first column  of export countries.
    
      for j=1:length(exp_match)  
        c=exp_match(j);
        ind_state=strfind(country,char(c));
        ind_match=find(not(cellfun('isempty', ind_state)));
    
        M(i,ind_match)=1; % Selective make elements of M 1 when there is match.
      end
    
    end
    
    M
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 2014-05-12
      • 2019-09-09
      • 1970-01-01
      • 1970-01-01
      • 2014-05-25
      相关资源
      最近更新 更多