规范化按第一列值分组的表变量

时间:2016-06-16 18:24:40

标签: matlab

我有下表(8行);

   Name       Age    Height    Weight    
__________    ___    ______    ______    

'Smith4'       30     71        176            
'Smith6'       80     69        163            
'Smith1'       10     64        131             
'Smith4'       40     67        133            
'James9'       49     64        119             
'James5'       56     45         56            
'James5'       87     56        890             
'James5'       23     56         43            

这里,4行中的每一行都是一组。我想规范每个小组的年龄。比如,史密斯'的最低年龄。将指向1和史密斯'的最大年龄。将指向100(并且休息将基于最大值和最小值)。同样的事情,我想和詹姆斯一起做。
有没有人知道如何在MATLAB中循环它?任何人都可以给我写代码吗?

我的原始资料:

     name                value 
______________________    ______________  

'kiemo_250'           1.3586
'kiemo_298-10M'       0.35857
'kiemo_298-12M'       0.48857
'kiemo_298-16M'       0.70429
'kiemo_298-24M'       0.97857
'kiemo_298-32M'       1.0429
'kiemo_298-5M'        0.012857
'kiemo_298-8M'        0.17857
'neywork_250'         1.01
'neywork_298-12M'     0.69714
'neywork_298-18M'     0.76286
'neywork_298-1M'      0.0057143
'neywork_298-3M'      0.29429
'neywork_298-5M'      0.47857
'neywork_298-6M'      0.54286
'neywork_298-8M'      0.61429
'man-10M'             0.58286
'man-14M'             0.56571
'man-18M'             0.51857
'man-24M'             0.55714
'man-30M'             0.51143
'man-4M'              0.39714
'man-8M'              0.52143
'man'                 0.40857
  ""                    ""
  ""                    "" 
  ""                    ""  
  ""                    ""

1 个答案:

答案 0 :(得分:0)

首先让我们构建表

t = table({'Smith4'; 'Smith6'; 'Smith1'; 'Smith4'; 'James1'; 'James5'; 'James5'; 'James5'}, [30 80 10 40 49 56 87 23]', 'VariableNames', {'Name', 'Age'})

%     Name      Age
%   ________    ___
%
%   'Smith4'    30 
%   'Smith6'    80 
%   'Smith1'    10 
%   'Smith4'    40 
%   'James1'    49 
%   'James5'    56 
%   'James5'    87 
%   'James5'    23 

您可以使用regexp确定主要姓氏。

lastname = regexp(t.Name, '^[A-Za-z]*', 'match', 'once');

%   'Smith'    'Smith'    'Smith'    'Smith'    'James'    'James'    'James'    'James'

然后使用unique的第三个输出为每个唯一的姓氏

分配唯一的ID
[~, ~, ind] = unique(lastname, 'stable');

%    1     1     1     1     2     2     2     2

然后您可以使用accumarray来规范化每个组

normalized = accumarray(ind, t.Age, [], @(x){(x - min(x)) ./ (max(x) - min(x))});

%   [4x1 double]    [4x1 double]

然后我们可以使用normalized展平cat,再乘以100以获得0100之间的值,然后替换t.Age

t.Age = cat(1, normalized{:}) * 100;

%     Name       Age  
%   ________    ______
%
%   'Smith4'    28.571
%   'Smith6'       100
%   'Smith1'         0
%   'James1'    40.625
%   'James5'    51.562
%   'James5'       100
%   'James5'         0

<强>更新

如果您希望标准化值在某个范围内(1 - 5),则可以执行以下操作。

lower = 1;
upper = 5;

normalized = accumarray(ind, t.Age, [], @(x){((x - min(x)) ./ (max(x) - min(x))) * (upper-lower) + lower});