给定三个 char 数组,假设 size(a) = [N,80]
,size(b) = [N,100]
; 大小(c) = [N,10]
;
当 N=5
a
、b
和 c
看起来像,
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
在 a
、b
和 c
中每个都有多达 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/