从表

时间:2017-03-22 06:31:28

标签: matlab random grouping combinatorics matlab-table

我会尝试在列表中写下我的问题,以便更容易理解:

  • 我有一个大小为T的matlab表1000x30
  • 最后一栏中的所有数据都称为' Class'表中的某些整数值范围为120
  • 所以有些行的值为1,这意味着这些行是" Class1"有些将具有值2,有些将具有值20,依此类推。
  • 具有特定类别的行数不等于该数量 有另一个类的行,所以可能有100行有类 1但10行有2类,500有类3,依此类推。

这就是我想要做的事情:

  • 我想获得具有最小类的行数 分配给它的行数。因此,我们假设类10使用count == 3分配的行数最少,而其他类的行分配超过3行。
  • 然后我会有一个名为YesNo的新列,其中只有01的值。
  • 然后,计数最少的类的所有行(例如本例中的Class 10)将具有值1
  • 对于包含所有其他类的其余行,我想从每个其他类中随机选择与数字最小的类相同数量的行(在此示例中它将是3)。
  • 然后,对于这些随机选择的每个类的行,新列YesNo中的值将为1,而未选择的其余行中的值将为0.
  • 因此,在此示例中,最终会出现一个包含1000值的新列,其中3 * 20将具有1&#3(3行分配给最低级别的行) count,20->是类的数量),其余为0。

我想知道如何在MATLAB R2015b中完成这项工作?我知道我可以使用T.YesNo = newArr;在表格中创建一个新列,其中newArr1000x1 double,其值为01

作为一个小例子,如果T10x3并且只有3个类(1,2,3),则下面是T的样子:

ID  Name    Class   
0   'a'     3
1   'b'     2
2   'a'     2
3   'b'     2
4   'a'     3
5   'a'     1
6   'a'     1
7   'b'     2
8   'b'     1
9   'a'     2

如上所示,Class3是计数最低的那个,只有2行。所以我想随机选择每个Class1和Class2的两行,然后将这些随机选择的行的新列的值设置为1,其余的将是0,如下所示:

ID  Name    Class   YesNo
0   'a'     3       1
1   'b'     2       0
2   'a'     2       1
3   'b'     2       0
4   'a'     3       1
5   'a'     1       0
6   'a'     1       1
7   'b'     2       0
8   'b'     1       1
9   'a'     2       1

1 个答案:

答案 0 :(得分:1)

见下面的代码。它应该是不言自明的。如果不清楚 - 请询问。

function q42944288
%% Definitions
MAX_CLASS = 20;
%% Setup
tmp = struct;
tmp.Data = rand(1000,1);
tmp.Class = uint8(randi(MAX_CLASS,1000,1)); % uint8 for efficiency
T = table(tmp.Data,tmp.Class,'VariableNames',{'Data','Class'});
%% Solution:
% Step 1:
[count,minVal] = min(histcounts(T.Class,'BinMethod','integers'));
% Steps 2+3:
T.YesNo = T.Class == minVal;
% Steps 4+5+6:
whichClass = bsxfun(@eq,T.Class,1:MAX_CLASS); % >=R2007a syntax
% whichClass = T.Class == 1:MAX_CLASS; % This is a logical array, >=R2016b syntax.
for indC = setdiff(1:MAX_CLASS,minVal) 
  inds = find(whichClass(:,indC));
  T.YesNo(inds(randperm(numel(inds),count))) = true; 
end
%% Test:
fprintf(1,'\nThe total number of classes is %d', numel(unique(T.Class)));
fprintf(1,'\nThe minimal count is %d',count);
fprintf(1,'\nThe total number of 1''s in T.YesNo is %d', sum(T.YesNo));