使用多个索引向量查找和计数字符串

时间:2015-08-22 08:36:00

标签: matlab

我有一个字符数组(如果更有用,也可以存储为单元格数组)(AsyncTask)并希望将两个不同索引的子字符串出现次数计算在两个单独的变量{{1 }和list

type

字符数组中不存在空格 - 为清晰起见而添加。

使用上面的示例,所需的输出将计算ind中每个list = C C N N C U C N N N C N U N C N C ind = 1 1 2 2 2 3 3 3 4 1 1 2 3 3 3 4 4 type = 15 15 15 15 15 15 15 15 15 16 16 16 16 16 16 16 16 和每个list的所有唯一字母实例 - 创建三列(对于C / N / U),每个类型有4行(每个ind)。这是使用每个数组中的条目出现的顺序完成的。

上述示例的所需输出(仅为清晰起见添加标签):

ind

我只知道如何使用单个索引执行此操作(使用type Type 15 Type 16 Ind C N U C N U 1 2 0 0 1 1 0 2 1 2 0 0 1 0 3 1 1 1 1 1 1 4 0 1 0 1 1 0 unique)。

我如何打赌用双重索引来做这件事?

2 个答案:

答案 0 :(得分:3)

一种可能性是通过减去例如将你的字母转换为双字母。 -64将数字 3 映射到字母 C

然后,您可以unique'rows''stable'一起使用,以获得以下结果:

list = char('CCNNCUCNNNCNUNCNC')
ind = [1 1 2 2 2 3 3 3 4 1 1 2 3 3 3 4 4]
type = [15 15 15 15 15 15 15 15 15 16 16 16 16 16 16 16 16]

data = [type(:) ind(:) (list(:) - 64)]
[a,~,c] = unique(data,'rows','stable')
occ = accumarray(c,ones(size(c)),[],@numel)

output = [a, occ]
output =

    15     1     3     2
    15     2    14     2
    15     2     3     1
    15     3    21     1
    15     3     3     1
    15     3    14     1
    15     4    14     1
    16     1    14     1
    16     1     3     1
    16     2    14     1
    16     3    21     1
    16     3    14     1
    16     3     3     1
    16     4    14     1
    16     4     3     1

如果您拥有统计信息工具箱,则应考虑使用grpstats

如果你不介意思维扭曲输出,那么crosstab是最简单的解决方案:

output = crosstab(type(:),ind(:),list(:)-64)

%// type in downwards, ind to the right
output(:,:,1) =   %// 'C'

     2     1     1     0
     1     0     1     1


output(:,:,2) =   %// 'N'

     0     2     1     1
     1     1     1     1


output(:,:,3) =  %// 'U'

     0     0     1     0
     0     0     1     0

以下一个班轮看起来像您想要的输出:

output2 = reshape(crosstab(ind(:),list(:)-64,type(:)),4,[],1)

output2 =

     2     0     0     1     1     0
     1     2     0     0     1     0
     1     1     1     1     1     1
     0     1     0     1     1     0

此外,在此工具箱中,您可以找到tabulate功能,该功能提供与accumarray结合的其他选项:

[~,~,c] = unique([type(:) ind(:)],'rows','stable')
output = accumarray(c(:),list(:),[],@(x) {tabulate(x)} )

enter image description here

还允许以下输出:

d = unique([type(:) ind(:) list(:)-64],'rows','stable')
output2 = [num2cell(d(:,[1,2])) vertcat(output{:})]

output2 = 

    [15]    [1]    'C'    [2]    [    100]
    [15]    [2]    'N'    [2]    [66.6667]
    [15]    [2]    'C'    [1]    [33.3333]
    [15]    [3]    'U'    [1]    [33.3333]
    [15]    [3]    'C'    [1]    [33.3333]
    [15]    [3]    'N'    [1]    [33.3333]
    [15]    [4]    'N'    [1]    [    100]
    [16]    [1]    'N'    [1]    [     50]
    [16]    [1]    'C'    [1]    [     50]
    [16]    [2]    'N'    [1]    [    100]
    [16]    [3]    'U'    [1]    [33.3333]
    [16]    [3]    'N'    [1]    [33.3333]
    [16]    [3]    'C'    [1]    [33.3333]
    [16]    [4]    'N'    [1]    [     50]
    [16]    [4]    'C'    [1]    [     50]

答案 1 :(得分:0)

使用accumarray

Output = accumarray([type',ind'],list');

您可能需要先使用typeliststr2num转换为数字,然后使用accumarray并使用num2str将结果转换回数字