matlab - 在 MATLAB 中有效地找到三个字符向量的唯一三元组

标签 matlab performance vector unique

给定三个 char 数组,假设 size(a) = [N,80]size(b) = [N,100]大小(c) = [N,10];

N=5 abc 看起来像,

ans =

  5×80 char array

‘efawefref’
‘Afreafraef’
‘afeafefaef’
‘afeafeaffa’
‘afeafaefae’

我想找到唯一条目(不是组合),这是 x = [a, b, c]

的唯一条目

当然我可以做 unique([a, b, c]) 但这对这些数据来说太慢了。 N~1e7

例子,

   a = [   'timon ';
        'simba ';
        'nala  ';
        'timon ';
        'mufasa'];

b = [   'boar   ';
        'lion   ';
        'lionese';
        'boar   ';
        'lion   '];

c = [   'chubby';
        'small ';
        'fat   ';
        'chubby';
        'fit   '];


unique([a,b,c],'rows')

ans =

  4×19 char array

    'mufasalion   fit   '
    'nala  lionesefat   '
    'simba lion   small '
    'timon boar   chubby'


size(unique([a,b,c],'rows'),1)

ans =

     4

有没有更聪明的方法来做到这一点?

编辑:答案的结果 对于这些尺寸的条目,

>> size(a)

ans =

    11724952          76

>> size(b)

ans =

    11724952          64

>> size(c)

ans =

    11724952           6

结果

@我的 radio

>> tic, size(unique(horzcat(a,b,c),'rows')), toc

ans =

     1038303         146

Elapsed time is 74.402044 seconds.

@gnovice 1

>> tic, size(unique(cellstr([a b c]))), toc

ans =

     1038303           1

Elapsed time is 77.044463 seconds.

@gnovice 2

>> tic, map = containers.Map(cellstr([a b c]), ones(length(a), 1)); size(map.keys.'), toc

ans =

     1038303           1

Elapsed time is 58.732947 seconds.

@沃尔菲

>> tic, size(unique( [categorical(cellstr(a)),categorical(cellstr(b)),categorical(cellstr(c))], 'rows' )), toc

ans =

     1038303           3

Elapsed time is 189.517131 seconds.

@obchardon

>> tic, x = primes(2000); a1 = prod(x(a+0),2); b1 = prod(x(b+0),2); c1 = prod(x(c+0),2); size(unique([a1,b1,c1],'rows')), toc

ans =

     1038258           3

Elapsed time is 46.889431 seconds.

我对最后一个感到困惑,我尝试了其他示例,但它总是给出略低的值。

最佳答案

为了模拟问题中更大的数据集,我使用 randi 创建了以下随机字符数组:

a = char(randi([65 90], [100 76]));      % Generate 100 76-character arrays
a = a(randi([1 100], [11724952 1]), :);  % Replicate rows: 11724952-by-76 result
b = char(randi([65 90], [100 64]));      % Generate 100 64-character arrays
b = b(randi([1 100], [11724952 1]), :);  % Replicate rows: 11724952-by-64 result
c = char(randi([65 90], [100 6]));       % Generate 100 6-character arrays
c = c(randi([1 100], [11724952 1]), :);  % Replicate rows: 11724952-by-6 result

abc 中每个都有多达 100 个独特的字符串,这将在连接时产生近 1,000,000 个独特的组合.

然后我测试了 3 个解决方案:原始使用 unique ,一种使用 cellstr 将字符数组转换为字符串元胞数组的变体避免使用 'rows' 参数,一个使用 containers.Map目的。最后一个将字符串作为键提供给 containers.Map 类(具有虚拟关联值)并让它创建一个映射,该映射将仅具有唯一字符串作为其键,然后您可以提取它。

由于这些测试至少需要 1 分钟才能运行,因此使用更准确的计时程序是不可行的 timeit (多次运行该函数以获得平均测量值)。因此我使用了tic/toc .以下是使用版本 R2018a 的一些典型结果:

>> clear d
>> tic; d = unique(horzcat(a, b, c), 'rows'); toc
Elapsed time is 726.324408 seconds.

>> clear d
>> tic; d = unique(cellstr([a b c])); toc
Elapsed time is 99.312927 seconds.

>> clear d
>> tic; map = containers.Map(cellstr([a b c]), ones(size(a, 1), 1)); d = map.keys.'; toc
Elapsed time is 89.853430 seconds.

这两个更快的解决方案的平均值通常大致相同,containers.Map 的平均速度稍快一些。它们都比使用带有 'rows' 参数的 unique 快得多,尽管这与帖子中使用版本 R2018b 的结果不一致。也许 unique 在较新版本中有重大更新,或者字符数组的特定内容可能非常重要(例如,是否所有字符串以大致相等的频率重复,数组是否排序或未排序等) .

关于matlab - 在 MATLAB 中有效地找到三个字符向量的唯一三元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57377443/

相关文章:

c++ - 使用 Matlab Coder 结合 matlab 代码和 mex 函数的 c/c++ 代码

sql - 使用 DISTINCT COUNT 的性能

arrays - 二色图像压缩算法

c++ - 通过引用传递 vector

c++ - 如何在递归函数中打印 vector ?

matlab - 如何通过 PRINT 函数以与 'Edit-->Copy Figure' 选项相同的质量将图形打印到剪贴板?

matlab - 从配置文件将小数解析为matlab

MATLAB "SIGMA must be symmetric and positive definite"错误有时没有意义

python - 性能分析仪

带有 std::map 的 C++ vector ?