Removing empty cells from cell array with multiple rows while preserving the rows

17 次查看(过去 30 天)
I have cell array of string values with empty cells in some of in the middle of some of the rows. I would like to delete the empty cells and shift the cells to the left but I don't want any shifting to happen in between rows. I tried the code below but it returns cell array of cell arrays. How can I modified the code so it returns a cell array of string values like the orginal array but only the empty cells removed?
compacted_instances = {};
for i = 1:size(instance_array_nolateral, 1)
% Get the current row
current_row = instance_array_nolateral(i,:);
current_row = {current_row};
% Remove empty cells from the current row
compacted_row = current_row(~cellfun('isempty', current_row));
% Store the compacted row in the new cell array
compacted_instances{i} = compacted_row;
end
  2 个评论
James Tursa
James Tursa 2024-5-9
编辑:James Tursa 2024-5-9
A cell array is a rectangular array by definition. You can shift things around (e.g., move stuff to the left to overwirte empty cells and move the empty cells to the right end), but you still have to have a rectangular array as a result. It is not entirely clear what your desired result should be. A cell array of string arrays, with each string array a different number of elements? Or ...? Could you post a small example of input and desired output?
Freddie
Freddie 2024-5-9
The array looks like this right now. It is an array with string values with some values missing in the middle of rows. I would like to remove the empty cells altogether and shift the cells in each row to the left. I do not mind having empty cells at the end of the rows in order to keep in rectangle. In this case this array has 104 rows and 13 columns. So I guess my desired outcome is another 104x13 arrays with all the empty cells shifted to the end of the rows.

请先登录,再进行评论。

采纳的回答

Voss
Voss 2024-5-9
C = { ...
'Right knee','Head','Elbow/forearm',[]; ...
'Hand/wrist',[],'Pelvis',[]; ...
[],[],'Ankle/foot',[]; ...
[],'Left knee',[],'Shoulder'; ...
}
C = 4x4 cell array
{'Right knee'} {'Head' } {'Elbow/forearm'} {0x0 double} {'Hand/wrist'} {0x0 double } {'Pelvis' } {0x0 double} {0x0 double } {0x0 double } {'Ankle/foot' } {0x0 double} {0x0 double } {'Left knee'} {0x0 double } {'Shoulder'}
Here's one way to move the empty cells to the right:
[~,cols] = sort(cellfun(@isempty,C),2);
[m,n] = size(C);
rows = repmat((1:m).',1,n);
C = C(sub2ind([m,n],rows,cols))
C = 4x4 cell array
{'Right knee'} {'Head' } {'Elbow/forearm'} {0x0 double} {'Hand/wrist'} {'Pelvis' } {0x0 double } {0x0 double} {'Ankle/foot'} {0x0 double} {0x0 double } {0x0 double} {'Left knee' } {'Shoulder'} {0x0 double } {0x0 double}
And if you then want to remove columns that contain only empty cells:
C(:,all(cellfun(@isempty,C),1)) = []
C = 4x3 cell array
{'Right knee'} {'Head' } {'Elbow/forearm'} {'Hand/wrist'} {'Pelvis' } {0x0 double } {'Ankle/foot'} {0x0 double} {0x0 double } {'Left knee' } {'Shoulder'} {0x0 double }
  2 个评论
Freddie
Freddie 2024-5-10
Thank you so much! I will have to study the code a few times to understand it but glad it works!
Voss
Voss 2024-5-10
编辑:Voss 2024-5-10
You're welcome!
The idea is: first do cellfun(@isempty,C) to get a matrix of logical (true/false) values the same size as C saying whether each cell of C is empty. Then sort(_,2) sorts each row of that logical matrix; since false (0) is less than true (1), the order is for the non-empty ones to go before the empty ones. The second output (cols) from sort() tells you which column the elements of C need to go to. Then the rows variable is just 1:m repeated for each column, since each element should stay in its own row. Finally, convert those row and column indices into linear indices using sub2ind(), and rearrange C using those linear indices to get the final result.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Shifting and Sorting Matrices 的更多信息

标签

产品

Community Treasure Hunt

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

Start Hunting!

Translated by