2

I am New to Matlab and I am stuck in efficiently solving the following problem.

I have two arrays (both of them 2D) and I want to check array1 col by col to know how many elements appear in each col of array2 (compare col to col)

for example

array1

    ---------
    'a1'  'b1'    'c1'   
    'd1'  'e1'    'f1'

array2
----------
    'a1'   'a1'   'b1'  'b1'  'a1' 
    'd1'   'd1'   'c1'  'd1'  'c1'
    'c1'   'c1'   'b1'  'd1'  'd1'

I am trying to get the following output

2 elements from array1 col1 appear in array2 col1
2 elements from array1 col1 appear in array2 col2
0 elements from array1 col1 appear in array2 col3
1 elements from array1 col1 appear in array2 col4
2 elements from array1 col1 appear in array2 col5

0 elements from array1 col2 appear in array2 col1
0 elements from array1 col2 appear in array2 col2
1 elements from array1 col2 appear in array2 col3
1 elements from array1 col2 appear in array2 col4
0 elements from array1 col2 appear in array2 col5

1 elements from array1 col3 appear in array2 col1
1 elements from array1 col3 appear in array2 col2
1 elements from array1 col3 appear in array2 col3
0 elements from array1 col3 appear in array2 col4
1 elements from array1 col3 appear in array2 col5
and so on

now I tried to do the below ugly code getting partial output

for i=1:size(Array1,2)
   for m=1:size(Array1,1)
     element = Array1(i,m);

     indx =find(ismember(Array2,element));
     Array_match(indx) = Array_match(indx) + 1;
     end
    for s=2:size(Array1,1)
    if  length(char(Array1(s,i))) > 0 
        tt= tt + 1;
    end
    length(Array_test_words(s,i))
    end
    Indx2 = find((Array_match) > tt);
 end
6
  • So it works and you would like input on how to improve the code or it does not work? Commented Sep 10, 2014 at 12:59
  • the behavior is not stable... when I try it one by one it works however, when I switch on the loop for one time run it gives me unexpected values. Commented Sep 10, 2014 at 13:01
  • Would those cells always have single character strings? Commented Sep 10, 2014 at 13:26
  • yes they always have N characters i mean if 1 char then all 1 char if 2 char then all elements will be 2 ...if we can do it for 1 or 2 chars will be enough for me Commented Sep 10, 2014 at 13:28
  • one more thnig, the size of array1 and array2 are unknow (only 2D) Commented Sep 10, 2014 at 13:34

2 Answers 2

3

Assuming that the input cell arrays have all the cells of single character strings, this might work for you -

%// Input cell arrays
array1 = {
    'a1' 'b1' 'c1'   
    'd1' 'e1' 'f1'}

array2 = {
        'a1'   'a1'   'b1'  'b1'  'a1' 
    'd1'   'd1'   'c1'  'd1'  'c1'
    'c1'   'c1'   'b1'  'd1'  'd1'}

%// Convert input cell arrays to numeric arrays
array1n = char(array1)-0
array1n = reshape(array1n(:,1) * 1000 + array1n(:,2),size(array1))

array2n = char(array2)-0
array2n = reshape(array2n(:,1) * 1000 + array2n(:,2),size(array2))

out = squeeze(sum(any(bsxfun(@eq,array2n,permute(array1n,[3 4 1 2])),1),3))

Output -

out =
     2     0     1
     2     0     1
     0     1     1
     1     1     0
     2     0     1
Sign up to request clarification or add additional context in comments.

5 Comments

@Aabualia Please edit your question with some reproducible code that includes generating the input arrays, so that we could test out the codes.
error : To RESHAPE the number of elements must not change.
@Aabualia Do both input cell arrays have all the cells of single character strings, as promised by you earlier in your comments?
@Aabualia hmm Please edit your question with something that is representative of such a data.
@Aabualia Check out the edits! Luis's solution deserves a look too!
2

Apply unique to the concatenation of both arrays to transform the cells into numeric labels. Remove repeated values in each column of the second array. Then test for equality with bsxfun and aggregate results for each combination of columns:

[~, ~, labels] = unique({array1{:} array2{:}});
a1 = reshape(labels(1:numel(array1)),size(array1)); %// array1 as numeric labels
a2 = reshape(labels(numel(array1)+1:end), size(array2)); %// same for array2
a2 = sort(a2);
a2(diff([NaN(1,size(a2,2)); a2])==0) = NaN; %// remove repeated values
m = bsxfun(@eq, permute(a1, [1 3 2]), permute(a2, [3 1 4 2])); %// find matches
result = squeeze(sum(reshape(m, [],size(a1,2),size(a2,2)), 1));

In your rexample this gives

result =
     2     2     0     1     2
     0     0     1     1     0
     1     1     1     0     1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.