Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to speed up strjoin on an N*M cell array?

59 views
Skip to first unread message

kj

unread,
May 22, 2013, 3:39:03 PM5/22/13
to


I have a cell array A of size N * M, containing only strings.

I want to efficiently generate the N * 1 matrix B such that B(K)
equals strjoin(A(K, :), SEP), for some separator string SEP.

I can always do this using a for-loop, but I've found it to be
extremely slow.

Is there a way to speed up the operation? (I'm thinking that maybe
there's a way to vectorize the operation, but I have not been able
to figure out how to do it.)


(In case it matters: N is of the order of 500,000; M is of the
order of 5; and the lengths of the strings A(I, J) range from 1 to
around 30.)

Thanks in advance!

kj

dpb

unread,
May 22, 2013, 4:18:48 PM5/22/13
to
On 5/22/2013 2:39 PM, kj wrote:
> I have a cell array A of size N * M, containing only strings.
>
> I want to efficiently generate the N * 1 matrix B such that B(K)
> equals strjoin(A(K, :), SEP), for some separator string SEP.
>
> I can always do this using a for-loop, but I've found it to be
> extremely slow.
>
> Is there a way to speed up the operation? (I'm thinking that maybe
> there's a way to vectorize the operation, but I have not been able
> to figure out how to do it.)

...

Isn't it just

B=strcat(A, (repmat(SEP,length(A),1))); % ?

The "trick" is that horzcat() needs to have same number of rows in the
two items being concatenated.

--

kj

unread,
May 23, 2013, 10:56:51 AM5/23/13
to
In <knj97p$fuf$1...@speranza.aioe.org> dpb <no...@non.net> writes:

>On 5/22/2013 2:39 PM, kj wrote:
>> I have a cell array A of size N * M, containing only strings.
>>
>> I want to efficiently generate the N * 1 matrix B such that B(K)
>> equals strjoin(A(K, :), SEP), for some separator string SEP.
>>
>> I can always do this using a for-loop, but I've found it to be
>> extremely slow.
>>
>> Is there a way to speed up the operation? (I'm thinking that maybe
>> there's a way to vectorize the operation, but I have not been able
>> to figure out how to do it.)

>...

>Isn't it just

>B=strcat(A, (repmat(SEP,length(A),1))); % ?


Thanks, but when I try this I get the error

Error using cell/strcat (line 45)
All the inputs must be the same size or scalars.

I'm sure that it's a simple typo somewhere, but I have not been
able to figure it out yet... (In case it isn't obvious, I'm a rank
noob MATLAB-wise.)

kj

unread,
May 23, 2013, 11:02:47 AM5/23/13
to
In <knlanj$vq$1...@reader1.panix.com> kj <no.e...@please.post> writes:

>In <knj97p$fuf$1...@speranza.aioe.org> dpb <no...@non.net> writes:

>>On 5/22/2013 2:39 PM, kj wrote:
>>> I have a cell array A of size N * M, containing only strings.
>>>
>>> I want to efficiently generate the N * 1 matrix B such that B(K)
>>> equals strjoin(A(K, :), SEP), for some separator string SEP.
>>>
>>> I can always do this using a for-loop, but I've found it to be
>>> extremely slow.
>>>
>>> Is there a way to speed up the operation? (I'm thinking that maybe
>>> there's a way to vectorize the operation, but I have not been able
>>> to figure out how to do it.)

>>...

>>Isn't it just

>>B=strcat(A, (repmat(SEP,length(A),1))); % ?


>Thanks, but when I try this I get the error

> Error using cell/strcat (line 45)
> All the inputs must be the same size or scalars.

Actually, I had meant to mention also that I get *exactly the same
error* when I run

B=strcat(A, repmat(SEP, size(A)));

which is truly *absurd*, since A and repmat(SEP, size(A)) have the
same size *by construction*...

Bruno Luong

unread,
May 23, 2013, 1:09:09 PM5/23/13
to

dpb

unread,
May 23, 2013, 2:50:28 PM5/23/13
to
The A will need to be the column under construction not the entire
array. I just used A as general syntax primarily to illustrate the
building of the column vector of SEP to match. So a specific case would be

B=strcat(A(1,:), (repmat(SEP,length(A),1))); %, say.

Looks like maybe Bruno knows of a File Exchange submission that may save
the explicit repmat, I don't know.

--

Bruno Luong

unread,
May 24, 2013, 2:33:09 AM5/24/13
to
See if the time is OK for you

% Data
M=500000; N=5;
sep = '/end';
% Fake Data
s = char('a'+floor(26*rand(M*N,10)));
A = reshape(cellstr(s),[M N]);
clear s

tic
c = A';
c(end,:) = {sep};
B = cell([N 1]);
for k=1:N
B{k} = CStr2String(c(:,k)); % FEX
end
toc % somewhere 0.5-0.8 seconds

% Bruno

Bruno Luong

unread,
May 24, 2013, 2:36:08 AM5/24/13
to
dpb <no...@non.net> wrote in message <knlodu$qol$1...@speranza.aioe.org>...
> On 5/23/2013 10:02 AM, kj wrote:

>
> Looks like maybe Bruno knows of a File Exchange submission that may save
> the explicit repmat, I don't know.

I don't really care about the repmat, which furthermore can be avoid without any special trick. The FEX allows mainly to speed up strcat itself.

Bruno

Bruno Luong

unread,
May 24, 2013, 2:49:20 AM5/24/13
to
Sorry I mix between dimensions. Let's start again:

% Data
M=5; N=500000;
sep = '/end';
% Fake Data
s = char('a'+floor(26*rand(M*N,10))); % 10 is the length of the strings
A = reshape(cellstr(s),[N M]);
clear s

tic
c = A';
B = cell([N 1]);
for k=1:N
B{k} = CStr2String(c(:,k),sep,false); % FEX
end
toc % 6.685762 seconds

tic
B = cell([N 1]);
for k=1:N
B{k} = strjoin(A(k,:),sep); % slow code
end
toc % Very long, 4 minutes

% Bruno

kj

unread,
May 24, 2013, 1:09:04 PM5/24/13
to
In <knn2hg$mec$1...@newscl01ah.mathworks.com> "Bruno Luong" <b.l...@fogale.findmycountry> writes:

>Sorry I mix between dimensions. Let's start again:

>% Data
>M=5; N=500000;
>sep = '/end';
>% Fake Data
>s = char('a'+floor(26*rand(M*N,10))); % 10 is the length of the strings
>A = reshape(cellstr(s),[N M]);
>clear s

>tic
>c = A';
>B = cell([N 1]);
>for k=1:N
> B{k} = CStr2String(c(:,k),sep,false); % FEX
>end
>toc % 6.685762 seconds



Thanks! CStr2String really does leave strjoin in the dust.

0 new messages