Divide matrix in subgroups
3 次查看(过去 30 天)
显示 更早的评论
Hello everyone, just a simple question : having a matrix X ,how can I divide the total number of columns in 24 subgroups and each subgroup give a number as variable name? Thanks.
采纳的回答
Star Strider
2021-4-15
Note that assigning each matrix to a different variable is not advisable. Keep them as the cell array, and refer to them as elements of it, using subscripts.
Dividing a (9x9) matrix into 9 (3x3) matrices would work as:
A = randi(9, 9);
Adiv = mat2cell(A, [1 1 1]*3, [1 1 1]*3);
.
14 个评论
Fercho_Sala
2021-4-15
@Star Strider it works good because you know the number of rows and columns, but for example; in the case you don't know the number of rows, and you just want to divide the number of rows according to a vector time, in this case 24 hours. How could you do it?
Star Strider
2021-4-15
I would need more information as to what your matrix contains, and how you want to divide it.
It is necessary to know all the dimensions of the matrix in order to use the mat2cell function.
Fercho_Sala
2021-4-15
Ok, I have a matrix (R) of size (249X1451), I need to divide the number of columns in 24. The matter is that normally I don’t know the number of columns, sometimes are more or sometimes are less this is aleatory, but always the number of columns fits into 24h because is the data for one day.
Here is an example of the way I cut the data, I know that for this especific case (:,1:151.1457) it means the first 2.5 hours(00:00 - 2:30). But sometimes that number of columns are no the same (1451) it changes and I have to recalculate the process when the matrix has another different number of columns. Thank you
P.S the number of rows is always equal.
smoothdata(((R(:,1:151.1457))),'movmedian',3,'omitnan');
Star Strider
2021-4-15
I have no idea what is in the matrix, or how the columns are designated.
If the first row are time values, it might be possible to use findgroups or unique to label the columns by the hour value, and then mat2cell could divide them appropriately given the number of common hours in each group. That would require a bit of extra code, however would likely not be a significant problem.
If there is no such designation, then it would likely not be possible to divide the columns correctly.
Fercho_Sala
2021-4-15
Star Strider
2021-4-15
编辑:Star Strider
2021-4-16
This turned out to be much more straightforward than I anticipated:
L1 = load('Fercho_Sala R.mat');
L2 = load('Fercho_Sala t.mat');
L3 = load('Fercho_Sala y.mat'); % Not Required For This
R = L1.A;
t = L2.A;
t = datevec(t);
[Ut,ia,idx] = unique(t(:,4)); % Unique Hours
Counts = accumarray(idx, 1); % Items In Each Hour
C = mat2cell(R, size(R,1), Counts); % Cell Array Of Partitioned ‘R’ Matrix
producing:
C =
1×24 cell array
Columns 1 through 5
{249×60 double} {249×57 double} {249×60 double} {249×61 double} {249×60 double}
...
Columns 21 through 24
{249×61 double} {249×61 double} {249×60 double} {249×61 double}
This was easier to do with datevec and accumarray than with findgroups and splitapply, at least for me.
Fercho_Sala
2021-4-19
@Star Strider how can I modify the script in the case I'd like to use this for every 3 or 6 hours?
Star Strider
2021-4-19
Interesting problem!
This works:
L1 = load('R.mat');
L2 = load('t.mat');
L3 = load('y.mat');
R = L1.A;
t = L2.A;
t = datevec(t);
[Ut,ia,idx] = unique(t(:,4)); % Unique Hours
Counts = accumarray(idx, 1); % Items In Each Hour
HoursGroup = 3; % Number Of Hours In Each Group
Countsmtx = reshape(Counts, HoursGroup, []); % Reshape ‘Counts’ Vector To Matrix
Counts = sum(Countsmtx); % Sum Columns To Get New ‘Groups’ Vector
C = mat2cell(R, size(R,1), Counts); % Cell Array Of Partitioned ‘R’ Matrix By ‘Groups’ Vector
It works by using reshape to create ‘Countsmtx’, and then sums the columns of the matrix to create a new ‘Counts’ vector.
Choose how you want to divide them with the ‘grouping’ variable ‘HoursGroup’ (here 3) that must be an integral divisor of 24 , so (1, 2, 3, 4, 6, 8, 12, 24). The code will fail for any other values.
Fercho_Sala
2021-4-21
@Star Strider that's the issue,, because normaly for this case it works good with an integral divisor of 24, however sometimes I just have to do it for every 30 minutes; in this case it will be a (0.5).
for the 30minutes option the easiest way is the one you provided before and I was wondering how I can divide each colum of the "C" (1X24) array, by the middle? Saying that this is just 30 minutes. Thanks.
Star Strider
2021-4-21
Try this:
L1 = load('R.mat');
L2 = load('t.mat');
L3 = load('y.mat');
R = L1.A;
t = L2.A;
tdn = datevec(t); % Date Vectors
MinutesGroup = 30; % Number Of Minutes In Each Group
group = rem(tdn(:,5), MinutesGroup)==0; % Grouping Variable ‘Steps’
[Ut,ia,idx] = unique(cumsum(+group)); % Unique Groups
Counts = accumarray(idx, 1); % Items In Each Group
C = mat2cell(R, size(R,1), Counts); % Cell Array Of Partitioned ‘R’ Matrix By ‘Groups’ Vector
It took a few minutes to figure out how to do this, and make it as robust as possible. This should allow any integer value of ‘MinutesGroup’ between 1 and numel(t) to define the partitions. (I checked it a number of different values for ‘MinutesGroup’ using the time vector as datevec rows, and it partitions everything correctly, at least with the data set provided.)
It might be possible to do a similar analysis with retime, however you requested a way to partition the data, not analyse it, and this code does exactly that.
Fercho_Sala
2021-4-22
@Star Strider yes, analysis of data is another different thing, thanks a lot for your knowledge. :)
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)