deleting numbers in cell array

I have a 32x5 cell array.
I want to delete all numbers (+/- 3 either side of each number) that do not appear in every column.
Is there a function that can help me?
Thanks
Sam

6 Comments

There is no built-in function for this purpose.
Please expand on the +/-3 part. Is that referring to row position? Column position?
The every column bit: is that to be determined for each cell entry individually, or is it referring to columns of the 32x5 cell?
What I meant by the +/- 3 part is: a buffer of plus and minus 3 either side of every number
I want to delete all values (+/- 3) that do not appear in every column.
its a bit confusing to explain.
if my cell array was:
10 11 10 28 9
39 40 41 40 39
58 67 58 57 59
I would want to delete: 28, 67
Cell arrays generally contain a different size of array for every entry, and might easily contain different data types.
You posted a numeric array, rather than a cell array.
There is no value that appears in every column of your array. The entries 9, 11, 41, 57, 59, 67 each appear only once in the array and so clearly do not appear in every column.
You did not answer my question about the +/-3. You thought you did, but you failed to add any more information than the original. So I have to ask again whether you are referring to horizontal position, or to vertical position, or to range of values. For example because 9 does not appear in every column, does that mean that entries with value 6, 7, 8, 9, 10, 11, 12 should all be deleted?
When values are deleted, what should replace them? Should the adjacent entries "fall down" to fill the hole?
You mentioned cell array before but I have to wonder whether it would be easier to use a numeric array and nan out what you do not want?
Perhaps you are trying to say that a values should be deleted if it is not the case that every column has some entry that is within the range value-3 to value+3? If you are, then I suspect that you think that after the deletions, that it will be the case that all entries of the resulting array will have the property of being within 3 of some entry from each column. However, that would not generally be the case: some of the values you delete for not having a match in every column, will be anchoring values in some columns, so after the deletion more values become unanchored.
Yes, I mean that values should be deleted if it is not the case that every column has some entry that is with the range of value-3 to value+3
Sorry I confused myself in the last post:
if the array was:
10 11 10 28 9
39 40 41 40 39
58 47 58 57 59
68 58 68 69 70
I would want to delete:
10 11 10 28 9
47
68 68 69 70
leaving:
39 40 41 40 39
58 58 68 69 70
when values are deleted I want them to be removed so the below entries moves up 'to fill the hole'.
So all values within value-3 to value+3 are in the same row.
I thought this may be easier to do with a cell array, however if a numeric array is best I can use that instead.
Thanks
Sam
The description of your problem is ambiguous. It is not clear how your algorithm should work neither the sequential order of commands is clear. I encourage you to describe the desired functionality step-by-step which might help you to write your own code quickly.
From what you wrote (but still not fitting your example values):
  1. Compare the first element of input matrix within its row with all other values.
  2. If all other values of said row are not within first element +/- 3, remove first element (by replacing it with NaN)
  3. Repeat steps 1 & 2 with all other values within input matrix.
  4. Move all remaining values (not NaN) as much rows up keeping the same column as possible without replacing or reordering numerical values.
Example:
dInput = [10 11 10 28 9; ...
39 40 41 40 39; ...
58 47 58 57 59; ...
68 58 68 69 70];
dInMin = dInput - 3;
dInMax = dInput + 3;
for numRow = 1:size(dInput,1)
for numCol = 1:size(dInput,2)
bRange = dInput(numRow,numCol) >= dInMin(numRow,:) & dInput(numRow,numCol) <= dInMax(numRow,:);
bRange(numCol) = 0;
if ~any(bRange)
dInput(numRow,numCol) = NaN;
end
end
end
dInput = [10 11 10 NaN 9
39 40 41 40 39
58 NaN 58 57 59
68 NaN 68 69 70]
Does it really make sense to move remaining values up?
Kind regards,
Robert
I want to find all values (value-3 to value+3) that are not present in every column and then delete these values.
I will try to describe it step-by-step:
Say the matrix is:
10 11 10 28 9
39 40 41 40 39
58 47 58 57 59
68 58 68 69 70
1) starting with the first element of the matrix (10). I want to search the other 4 columns to determine if they all contain a number between 7 and 13 (10-3 and 10+3).
2) column two contains 11, column three contains 10 and column five contains 9. However there is no number between 7 and 13 in column four.
3) therefore I would delete all of these numbers (10 11 10 9).
4) I would then move on to '28'. none of the other columns contain any number between 25 and 31 (28-3 and 28+3). therefore I would delete 28
5) I would then move on to '39'. all five columns contain a number between 36 and 42 (39-3 and 39+3). therefore I would keep all of these numbers (39 40 41 40 39).
6) moving on to '58' all five columns contain a number between 55 and 61 (58-3 and 58+3). therefore I would keep all of these numbers (58 58 58 57 59).
7) moving onto '47' none of the other columns contain a number between 43 and 50 (47-3 and 47+3). therefore I would delete 47.
8) moving onto '68' all columns except column two contain a number between 65 and 71 (68-3 and 68+3). therefore I would delete all of these numbers (68 68 69 70).
9) This would leave me with:
NaN NaN NaN NaN NaN
39 40 41 40 39
58 NaN 58 57 59
NaN 58 NaN NaN NaN
10) I want to make it so all numbers move up when the number above it is deleted so all numers -3 to +3 are in the same row, as below:
39 40 41 40 39
58 58 68 69 70
Hope this make is more clear. Sorry it is so wordy

Sign in to comment.

 Accepted Answer

Hi sam van Bohemen,
Thank you for your description. I guess the following code will do the trick:
dInput = [10 11 10 28 9; ...
39 40 41 40 39; ...
58 47 58 57 59; ...
68 58 68 69 70];
dInMin = dInput - 3;
dInMax = dInput + 3;
for numRow = 1:size(dInput,1)
for numCol = 1:size(dInput,2)
bRange = all(any(dInput(numRow,numCol) >= dInMin(:,[1:numCol-1,numCol+1:end]) & dInput(numRow,numCol) <= dInMax(:,[1:numCol-1,numCol+1:end]),1));
if ~bRange
dInput(numRow,numCol) = NaN;
end
end
end
bRowMoved = true;
while bRowMoved
for numRow = 2:size(dInput,1)
bRowMoved = false;
for numCol = 1:size(dInput,2)
if isnan(dInput(numRow-1,numCol))
dInput(numRow-1,numCol) = dInput(numRow,numCol);
dInput(numRow,numCol) = NaN;
bRowMoved = true;
end
end
end
dInput(all(isnan(dInput),2),:) = [];
end
Kind regards,
Robert

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!