Raldenors
Raldenors

Reputation: 311

Find the same values in another column in matlab

i want to find same values of number in different column, for example i have a matrix array:

A = [1  11  0.17
2   1   78
3   4   90
45  5   14
10  10  1]

so as you can see no. 1 in column 1 have the same values in column 2 and column 3, so i want to pick that number and put into another cell or matrix cell

B= [1]

and perform another operation C/B, letting C is equal to:

C= [1
3
5
7
9]

and you will have:

D= [1   11  0.17    1
2   1   78  3
3   4   90  5
45  5   14  7
10  10  1   9]

then after that, values in column 4 have equivalent numbers that we can define, but we will choose only those number that have number 1, or B in theirs row

define:

1-->23
3 -->56
9 --> 78

then we have, see image below: enter image description here

so how can i do that? is it possible? thanks

Upvotes: 0

Views: 450

Answers (1)

rayryeng
rayryeng

Reputation: 104515

Let's tackle your problem into steps.

Step #1 - Determine if there is a value shared by all columns

We can do this intelligently by bsxfun, unique, permute and any and all.

We first need to use unique so that we can generate all possible unique values in the matrix A. Once we do this, we can look at each value of the unique values and see if all columns in A contain this value. If this is the case, then this is the number we need to focus on.

As such, do something like this first:

Aun = unique(A);
eqs_mat = bsxfun(@eq, A, permute(Aun, [3 2 1]));

eqs_mat would generate a 3D matrix where each slice figures out where a particular value in the unique array appeared. As such, for each slice, each column will have a bunch of false values but at least one true value where this true value tells you the position in the column that matched a unique value. The next thing you'll want to do is go through each slice of this result and determine whether there is at least one non-zero value for each column.

For a value to be shared along all columns, a slice should have a non-zero value per column.

We can eloquently determine which value we need to extract by:

ind = squeeze(all(any(eqs_mat,1),2));

Given your example data, we have this for our unique values:

>> B

B =

    0.1700
    1.0000
    2.0000
    3.0000
    4.0000
    5.0000
   10.0000
   11.0000
   14.0000
   45.0000
   78.0000
   90.0000

Also, the last statement I executed above gives us:

>> ind

ind =

     0
     1
     0
     0
     0
     0
     0
     0
     0
     0
     0
     0

The above means that the second location of the unique array is the value we want, and this corresponds to 1. Therefore, we can extract the particular value we want by:

val = Aun(ind);

val contains the value that is shared along all columns.

Step #2 - Given the value B, take a vector C and divide by B.

That's pretty straight forward. Make sure that C is the same size as the total number of rows as A, so:

C = [1 3 5 7 9].';
B = val;
col = C / B;

Step #3 - For each location in A that shares the common value, we want to generate a new fifth column that gives a new value for each corresponding row.

You can do that by declaring a vector of... say... zeroes, then find the right rows that share the common value and replace the values in this fifth column with the values you want:

zer = zeros(size(A,1), 1);
D = [23; 56; 78];
ind2 = any(A == val, 2);
zer(ind2) = D;

%// Create final matrix
fin = [A col zer];

We finally get:

>> fin

fin =

    1.0000   11.0000    0.1700    1.0000   23.0000
    2.0000    1.0000   78.0000    3.0000   56.0000
    3.0000    4.0000   90.0000    5.0000         0
   45.0000    5.0000   14.0000    7.0000         0
   10.0000   10.0000    1.0000    9.0000   78.0000

Take note that you need to make sure that what you're assigning to the fifth column is the same size as the total number of columns in A.

Upvotes: 1

Related Questions