Label segments based on percentage
Afficher commentaires plus anciens
Hi,
I have a variable (AL_128 which I have attached). It is a 1x48 cell where each cell is a Ax20 matrix. The matrices contain the values 0 and 1. For instance, cell 1 is a 225x20 matrix which should be interpret as follows: 225 segments where each segment is of length 20.
What I want to do here is to say that if 30% of the segments contain the label 1, the whole segment should be labelled 1. Therefore, cell 1 will end up being a 225x1 vector. This should be done for all segments and all cells.
How can I do that?
Réponse acceptée
Plus de réponses (1)
Image Analyst
le 13 Déc 2019
Your data didn't seem to have any segments where the value was 1, at least in the several cells I looked in, but I think this should work and be pretty easy to follow and understand.
s = load('AL_128.mat')
AL_128 = s.AL_128
% Define output cell array
output = cell(size(AL_128));
for k = 1 : length(AL_128)
% Get the contents of this cell
thisCellsContents = AL_128{k}; % This is an N rows - by - 20 columns matrix.
[rows, columns] = size(thisCellsContents); % Get the number of rows and columns in this matrix.
% See which rows contain a 1 in any column
containsA1 = any(thisCellsContents == 1, 2); % This is a N row vector.
% See if the number of them is 30% or more of the rows
fractionContaining1 = sum(containsA1) / rows;
if fractionContaining1 >= 0.3
output{k} = ones(rows, 1); % Make vector of all 1's
else
output{k} = thisCellsContents; % Just the original contents.
end
end
% Overwrite input, if desired.
AL_128 = output
10 commentaires
Image Analyst
le 15 Déc 2019
I think that's because, as I said, there are no 1's in your any of your matrices, so the criteria of the "if" never got satisfied and so this statement never got executed:
output{k} = ones(rows, 1); % Make vector of all 1's
so no vector ever got created. If you do have a cell array where some cells contain a matrix where at least 30% of the rows contain a 1, then attach it and I'll check it.
Uerm
le 15 Déc 2019
Image Analyst
le 15 Déc 2019
So "Each row is considered a segment. If a segment contains at least 30% 1's, then the whole segment should be 1." meaning the whole row should be 1, meaning the matrix is the same size, just that certain rows (where more than 30% of the values are 1) should be all 1's.
That's not what I did. I made a column vectors, except in those cases where not more than 30% were 1's and in that case I left the matrix alone. But you also said "should end as a 225x1 vector". So I think your statements are contradictory and I don't know whether you want segments/rows to be set to all 1 in the existing matrix, or if you want a vector where only some elements are 1 (where the row is 30% or more with 1's). I also don't know what you want to do with the existing matrices where the 30% criteria is not met. I just left those alone, but is that what you want?
If you put in an fprintf statement
s = load('AL_128.mat')
AL_128 = s.AL_128
% Define output cell array
output = cell(size(AL_128));
for k = 1 : length(AL_128)
% Get the contents of this cell
thisCellsContents = AL_128{k}; % This is an N rows - by - 20 columns matrix.
[rows, columns] = size(thisCellsContents); % Get the number of rows and columns in this matrix.
% See which rows contain a 1 in any column
containsA1 = any(thisCellsContents == 1, 2); % This is a N row vector.
% See if the number of them is 30% or more of the rows
fractionContaining1 = sum(containsA1) / rows;
if fractionContaining1 >= 0.3
fprintf('Setting cell #%d to a %d-row column vector\n', k, rows);
output{k} = ones(rows, 1); % Make vector of all 1's
else
output{k} = thisCellsContents; % Just the original contents.
end
end
% Overwrite input, if desired.
AL_128 = output
then you'll see
Setting cell #25 to a 186-row column vector
Setting cell #26 to a 210-row column vector
Setting cell #27 to a 277-row column vector
Setting cell #32 to a 261-row column vector
Setting cell #38 to a 213-row column vector
Setting cell #40 to a 239-row column vector
so I made those cells into vectors.
If on the other hand you want to replace the matrix in each cell with a vector where it's one if more than 30% in that particular row are 1, and zero where less than 30% are 1, then run this code:
s = load('AL_128.mat')
AL_128 = s.AL_128
% Define output cell array
output = cell(size(AL_128));
for k = 1 : length(AL_128)
% Get the contents of this cell
thisCellsContents = AL_128{k}; % This is an N rows - by - 20 columns matrix.
[rows, columns] = size(thisCellsContents); % Get the number of rows and columns in this matrix.
% See which rows contain a 1 in any column
num1sPerRow = sum(thisCellsContents == 1, 2); % This is a N row vector.
% See if the number of them is 30% or more of the columns.
fractionContaining1 = num1sPerRow / columns;
if fractionContaining1 >= 0.3
fprintf('Setting cell #%d to a %d-row column vector\n', k, rows);
vec = zeros(rows, 1); % Initialize.
vec(fractionContaining1 > 0.3 * columns) = 1; % Set certain rows to 1.
output{k} = vec; % Make vector of 0's and 1's
else
output{k} = thisCellsContents; % Just the original contents.
end
end
% Overwrite input, if desired.
% AL_128 = output
You'll see
Setting cell #32 to a 261-row column vector
Setting cell #40 to a 239-row column vector
But again, I'm not sure if you want matrices or vectors. You've said it both ways. And I've given two ways of doing it. If neither is what you want then you'll just have to give an example and explain it. And have some cases where the matrices are a mix of 0s and 1s, not all 0 or 1 like you have now.
Uerm
le 15 Déc 2019
Image Analyst
le 15 Déc 2019
And didn't my second chunk of code in my last comment do that?
Again, please attach your actual matrix.
And say what you want to happen with the cell contents if the 30% criteria is not met. Do you want the original A-by-20 matrix, or do you want some kind of column vector for that case also?
Image Analyst
le 16 Déc 2019
OK, the picture helped. Try this:
s = load('AL_128.mat')
AL_128 = s.AL_128
% Define output cell array
output = cell(size(AL_128));
for k = 1 : length(AL_128)
% Get the contents of this cell
thisCellsContents = AL_128{k}; % This is an N rows - by - 20 columns matrix.
[rows, columns] = size(thisCellsContents); % Get the number of rows and columns in this matrix.
% See which rows contain a 1 in any column
num1sPerRow = sum(thisCellsContents == 1, 2); % This is a N row vector.
% See if the number of them is 30% or more of the columns.
fractionContaining1 = num1sPerRow / columns;
fprintf('The highest fraction of ones any row in matrix #%d has is %.2f.\n', k, max(fractionContaining1));
% Say what rows need to be set to 1 and which need to be set to zero.
indexesToSetTo1 = fractionContaining1 > 0.3;
if any(indexesToSetTo1)
fprintf('Setting cell #%d to a %d-row column vector\n', k, rows);
output{k} = indexesToSetTo1; % Make vector of 0's and 1's
else
fprintf('Leaving cell #%d alone.\n', k);
output{k} = thisCellsContents; % Just the original contents.
end
end
% Overwrite input, if desired.
% AL_128 = output
Uerm
le 18 Déc 2019
Catégories
En savoir plus sur Linear Predictive Coding dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!