如何在Matlab中用另一个不同大小数组的对应值替换表格列的某些元素?

Posted

技术标签:

【中文标题】如何在Matlab中用另一个不同大小数组的对应值替换表格列的某些元素?【英文标题】:How to replace certain elements of table column with corresponding values of another array of different size in Matlab? 【发布时间】:2016-02-12 05:48:26 【问题描述】:

我有一个 categorical 表变量 alloptions.Exp(96399 行),其值如下:

'Mar1 15'
'Mar1 15'
'Mar1 15'
'Mar1 15'
'Mar 15'
'Mar 15'
'Mar 15'
'Apr1 15'
'Apr2 15'
'Apr 15'
'Apr4 15'
'May1 15'
'May2 15'
'May 15'
'May4 15' ....

我有一个 119x2 Expiration_Table 数组,其中包含以下值:

'Mar1 15'   '06-Mar-2015'
'Mar2 15'   '13-Mar-2015'
'Mar 15'    '20-Mar-2015'
'Mar5 15'   '31-Mar-2015'
'Apr1 15'   '02-Apr-2015'
'Apr2 15'   '10-Apr-2015'
'Apr 15'    '17-Apr-2015'
'Apr4 15'   '24-Apr-2015'
'May1 15'   '01-May-2015'
.....

我需要创建另一个表变量 alloptions.ExpDate 具有来自 Expiration_Table(:,2) 的相应值,即来自第二列。

有没有更好的方法不使用循环?

【问题讨论】:

我怀疑ismember 会帮助你。但是您能否将问题中的示例数据更改为实际的 MATLAB 语法,以一种可以将其复制并粘贴到 MATLAB 中的方式创建分类表? 底层的字符串是这样的吗?如果您尝试将字符串 'Mar1 15' 与 '01-Mar-2015' 进行比较,它将无法正常工作。您首先需要将字符串转换为通用格式,例如。使用日期编号 【参考方案1】:

这个怎么样?

[v, w] = ismember(alloptions, Expiration_Table(:,1));
result = Expiration_Table(w(v),2);

在您的示例中,使用

alloptions = 'Mar1 15'
              'Mar1 15'
              'Mar1 15'
              'Mar1 15'
              'Mar 15'
              'Mar 15'
              'Mar 15'
              'Apr1 15'
              'Apr2 15'
              'Apr 15'
              'Apr4 15'
              'May1 15'
              'May2 15'
              'May 15'
              'May4 15';
Expiration_Table = 'Mar1 15'   '06-Mar-2015'
                    'Mar2 15'   '13-Mar-2015'
                    'Mar 15'    '20-Mar-2015'
                    'Mar5 15'   '31-Mar-2015'
                    'Apr1 15'   '02-Apr-2015'
                    'Apr2 15'   '10-Apr-2015'
                    'Apr 15'    '17-Apr-2015'
                    'Apr4 15'   '24-Apr-2015'
                    'May1 15'   '01-May-2015'

结果是

result = 
    '06-Mar-2015'
    '06-Mar-2015'
    '06-Mar-2015'
    '06-Mar-2015'
    '20-Mar-2015'
    '20-Mar-2015'
    '20-Mar-2015'
    '02-Apr-2015'
    '10-Apr-2015'
    '17-Apr-2015'
    '24-Apr-2015'
    '01-May-2015'

如果alloptions分类,这也有效,例如在上述定义之后运行alloptions = nominal(alloptions);

注意

如果alloptions 中的值与Expiration_Table 中的多行匹配,则选择第一个。 在Expiration_Table 中没有匹配行的alloptions 值将被忽略。如果您希望将它们设置为 预定义值,例如空字符串,请使用以下修改后的代码:

将未找到的值设置为预定义值的修改代码:

[v, w] = ismember(alloptions, Expiration_Table(:,1));
result = repmat('', numel(alloptions), 1); %// initiallize to predefined value
result(v) = Expiration_Table(w(v),2);

给了

result = 
    '06-Mar-2015'
    '06-Mar-2015'
    '06-Mar-2015'
    '06-Mar-2015'
    '20-Mar-2015'
    '20-Mar-2015'
    '20-Mar-2015'
    '02-Apr-2015'
    '10-Apr-2015'
    '17-Apr-2015'
    '24-Apr-2015'
    '01-May-2015'
    ''
    ''
    ''

【讨论】:

ismember 的使用很好,我认为它有效。不过,我仍然会为使用外连接提供一个插件:P 这真的感觉像是一个经典的 SQL 表连接问题,并且使用表和 SQLish 语法对我来说似乎更透明! 一个小评论:如果 expire_table 的第一列有重复元素,我的回答和 Mendo 的会有不同的行为。 @MatthewGunn 我不知道outerjoin。我很少使用table 数据类型:-)【参考方案2】:

没有。没有更好的方法可以做到这一点,因为名称可能不是唯一的。例如,考虑 Expiration_Table 的以下文本:

'Mar1 15'   '06-Mar-2015'
'Mar1 15'   '13-Mar-2015'
'Mar 15'    '20-Mar-2015'
...

如果我们在第一列中有重复的元素在第二列中有不同的对应值会发生什么。

或者如果程序在第一列中找不到任何相同的名称该怎么办?

【讨论】:

谢谢你们)你们是真正的 matlab 极客)。 Luis 的代码确实以最优雅的方式工作。我对其进行了一些修改,并将所有选项更正为 alloptions.Exp。我真正需要的是向表中添加一个新变量,即缺少过期的预定义值。如果 Luis 不这样做,我将无法添加新列,因为行数必须相同。【参考方案3】:

是的!在数据库语言中,您要求进行表连接。如果您的数据在 MATLAB 中的“表”变量类型中,您可以在一个公共变量上连接两个表。如果您希望 table1 中的所有行都进入您的新表,您需要一个左外连接。在 R2015b 中,语法为:

new_table = outerjoin(my_table, expiration_table,'Type','left');

我相信早期版本的 MATLAB 可能有不同的语法。几个cmets:

    这段代码假设my_table和expiration_table有一个同名的变量,同名的变量就是你要匹配的变量。如果没有,您可以指定“LeftKey”等... 请注意,如果 expire_table 有多个具有相同值的行,您将在新表中获得一行 FOR EACH POSSIBLE PAIRING! 它还假设每个表中的公共变量是可比较的。如果你有不同的字符串/奇怪的格式,你可能需要转换成类似的东西,比如 datenum(例如x = datenum(char(date_categorical))

外连接示例。盯着tt2两张表

 t.d                     t2.d        t2.n
 ___                     _____       ____
'jan'                    'feb'        2
'feb'                    'asdf'       0
'mar'                    'feb'        2.1
                         'mar'        3

outerjoin(t, t2,'Type','left') 会返回:

 d_t     d_t2      n 
_____    _____    ___
'feb'    'feb'      2
'feb'    'feb'    2.1
'jan'    ''       NaN
'mar'    'mar'      3

【讨论】:

以上是关于如何在Matlab中用另一个不同大小数组的对应值替换表格列的某些元素?的主要内容,如果未能解决你的问题,请参考以下文章

matlab中结构体和cell的区别

matlab中如何计算二维数组大小?

matlab 灰度图像矩阵的大小问题(入门级)

Matlab中用内建函数代替for循环

Python Numpy:用另一个数组中的对应值替换一个数组中的值

matlab中plot(2,2)是啥意思