在Matlab中,如果值沿列变化,如何获取新变量

在Matlab中,如果值沿列变化,如何获取新变量,matlab,variables,cell,Matlab,Variables,Cell,如何仅通过观察值随年份(列)变化的行获取新变量(输出)。(例如:第1行)?(不考虑第一栏) 范例 输入: Title x '97 '99 '00 '01 '02 %row1 13 189 189 39 39 39 16 183 183 183 183 183 18 76 76 76 28 28 22 [] [] 123 123 123 25 12 12 12 [] [] 输出: x '97 '99 '00 '01 '

如何仅通过观察值随年份(列)变化的行获取新变量(输出)。(例如:第1行)?(不考虑第一栏) 范例

输入:

Title x '97 '99 '00 '01 '02 
%row1 13 189 189 39  39  39
      16 183 183 183 183 183
      18 76  76  76  28  28
      22 []  []  123 123 123
      25 12  12  12  []  []
输出:

  x '97 '99 '00 '01 '02 
  13 189 189 39  39  39
  18 76  76  76  28  28

我假设你的矩阵是一个2D单元数组。如你所说,我们将忽略第一列。基本程序如下:

  • 创建一个新的单元格数组,其行数与原始单元格数组的行数相同
  • 对于原始单元格数组的每一行,将每一行转换为向量,并将其作为新单元格数组中的元素放置。每个行的空白条目将被忽略。我们不能进行矢量化,因为每一行都可能是不均匀的,因此需要一个循环
  • 对于每行,使用
    diff
    查找每行中相邻元素之间的差异。如果任何项都是非零的,那么这是我们需要的一行。此步骤的输出将是与列中没有更改的行相匹配的行列表
  • 使用步骤#3中的索引并将原始单元格数组子集

  • 不言而喻:

    %// Sample data
    A = {13 189 189 39  39  39
        16 183 183 183 183 183
        18 76  76  76  28  28
        22 []  []  123 123 123
        25 12  12  12  []  []};
    
    %// Create new cell array that contains
    %// the rows of your cell array converted into a vector
    B = cell(size(A,1),1);
    
    %// For each row, extract everything but the first column
    %// and convert to a vector
    for ind = 1 : size(A,1)
        B{ind} = cell2mat(A(ind,2:end));
    end
    
    %// Find those rows where we
    %// find at least one transition
    C = cellfun(@(x) any(diff(x) ~= 0), B);
    
    %// Subset your original cell matrix
    %// to just have these rows
    finalMat = A(C,:)
    

    让我们慢慢地逐步完成这段代码。我根据你的帖子创建了你的原始单元格数组。下一行代码将创建一个空白单元格数组,其中的元素数与原始矩阵中的行数相同。下一行代码有一个
    for
    循环,它遍历原始矩阵的每一行。对于每一行,忽略第一列并抓取所有其他列。这将提取每行的所有单元格。我们希望将其转换为元素的法向量,这就是为什么在提取每行的单元格后使用
    cell2mat
    。然后将这个向量放在我们以前创建的空白单元格数组中的相应位置。

    我们必须这样做,因为每一行可能都有空元素,因此如果我们在整个2D单元格矩阵上执行
    cell2mat
    ,我们将得到一个维度不一致的错误。所有行的列数必须相同。然后我们使用<代码> CyFrase重复遍历空白(现在填充的)单元数组中的所有单元格。每个单元格元素将包含我们查看的原始单元格矩阵的每一行,所有空元素都将被忽略。对于每个单元元素/行向量,我们使用
    diff
    获取数组中元素对的差异
    diff
    的工作原理如下:对于数组
    x
    中索引
    i
    处的值,数组
    y
    的索引
    i
    处的输出为:

    y_i = x_{i+1} - x_i
    
    因此,如果行向量具有所有相同的元素,那么这将生成一个完整的零数组。如果至少有一个更改,那么这是我们需要提取的一行,这就是为什么我们要执行
    any(diff(x)~=0)
    。如果行向量中至少有一个更改,我们将输出
    true
    1
    。如果所有元素都相同,则输出
    false
    0
    。然后,
    cellfun
    的输出将告诉我们某一行是否是我们要查找的行。然后,我们使用此输出对原始单元格数组进行子集设置,以过滤掉在所有列上都有一些转换的行


    输入:

    A = 
    
     [13]    [189]    [189]    [ 39]    [ 39]    [ 39]
     [16]    [183]    [183]    [183]    [183]    [183]
     [18]    [ 76]    [ 76]    [ 76]    [ 28]    [ 28]
     [22]       []       []    [123]    [123]    [123]
     [25]    [ 12]    [ 12]    [ 12]       []       []
    
    您的输出存储在
    finalMat
    中,它看起来像:

    finalMat = 
    
     [13]    [189]    [189]    [39]    [39]    [39]
     [18]    [ 76]    [ 76]    [76]    [28]    [28]
    

    空白条目是什么?您的变量是否存储为单元格数组?我认为OP需要那些行,如果忽略空白项,则显示至少一个行的行(即,<代码>任何(DIFF(行,:)= 0</代码>)),这是一个不被考虑的行。@ Shai我的变量被存储为单元格数组“是”。我的空白条目是没有对应值的条目。它们也可以是“0”或“NaN”。导致空白条目的代码如下:<代码> B(ArayFun)(@(x)ISHOLD(STREST(IDX(x,,),[1 1)],1:大小(IDX,1)),())= [];<代码>Oops,更正我之前的评论。如果至少有一个更改,则这是您提取的一行。对于那些显示连续元素没有变化的行,可以将其过滤掉。我已经写了答案。哇。我刚刚看到你对答案的“描述性”编辑。非常感谢你。我会仔细阅读,但我相信它会对我的学习非常有用。非常感谢。