在Matlab中对数据进行排序

时间:2011-06-22 10:12:14

标签: matlab sorting join

我希望国家A的产品编号(第1列)和年份(第2列)与国家B的相同产品和年份匹配,以便能够减去相应的交易编号(第3列减去第6列)那一年的国家和那个产品。如果找不到对方,我希望将该帖子丢弃。

在下面链接的示例中,我手动完成此操作直到第22行(​​除了减去交易数字)。例如,下面的行(23)表示产品030420在1995年以2.823的价格进行交易,但该国家的B中没有记录该产品的交易,所以我希望删除该帖子。相应地,在B国,产品030420的贸易记录于1994年,但国家A没有对应的,因此该职位也应删除。

即使以下示例中的数据显示在excel中(我试图在excel中解决这个问题但是它很棘手)我现在将数据存储在Matlab中的矩阵中并想为它编写代码,但是我对Matlab /编码很新。用语言来说可能是这样的:

  • 如果第1栏中的第一个条目=第4栏中的任何条目
  • 然后,如果第2列中的第一个条目=第5列中的任何条目,则从第3列的第一个条目中减去交易数字(第6列,无论它最终在哪里找到)。
  • 如果找不到匹配项,我希望程序按上述方式抛出该帖子。

然后当然重复其余样本的程序。

示例:

http://img228.imageshack.us/img228/1214/skrmavbild20110609kl092.png

如果有人想阅读这篇较短的文章并提出任何建议,我们将不胜感激。

1 个答案:

答案 0 :(得分:2)

在此解决方案中,我将使用统计工具箱中的 Dataset Arrays

考虑以下两个示例CSV文件(类似于您的Excel文件,但我将这两个国家划分为单独的文件):

countryA.csv

ProductCode,Year,TradeValue
011111,1992,5.934
011111,1999,7.05
022222,2002,5.2
033333,2005,16.6
033333,2006,55

countryB.csv

ProductCode,Year,TradeValue
011111,1992,24.5
011111,1999,25
033333,2005,33.11
033333,2006,44.92
044444,2010,10.8

下面的代码读取两个数据集,并使用(ProductCode,Year)作为行键执行内部join,然后我们计算匹配行的两个交易值的差异:

%# read datasets (note we are reading ProductCode/Year as strings to preserve leading zeros)
dA = dataset('File','countryA.csv', 'Delimiter',',', 'Format','%s %s %f','ReadVarNames',true);
dB = dataset('File','countryB.csv', 'Delimiter',',', 'Format','%s %s %f','ReadVarNames',true);

%# inner join (keep only rows that exist in both datasets)
ds = join(dA, dB, 'keys',{'ProductCode' 'Year'}, 'type','inner', 'MergeKeys',true);

%# add a new variable for the difference
dsTradeDiff = dataset(ds.TradeValue_left - ds.TradeValue_right, 'VarNames','TradeDifference');
ds = cat(2, ds, dsTradeDiff);

结果数据集:

ds = 
    ProductCode     Year          TradeValue_left    TradeValue_right    TradeDifference
    '011111'        '1992'        5.934               24.5               -18.566        
    '011111'        '1999'         7.05                 25                -17.95        
    '033333'        '2005'         16.6              33.11                -16.51        
    '033333'        '2006'           55              44.92                 10.08   

编辑:这是另一种实现上述方法的方法,只使用基本的内置MATLAB函数:

%# read countryA
fid = fopen('countryA.csv','rt');
C = textscan(fid, '%s %s %f', 'Delimiter',',', 'HeaderLines',1);
fclose(fid);
[prodCodeA yearA tradeValA] = deal(C{:});

%# read countryB
fid = fopen('countryB.csv','rt');
C = textscan(fid, '%s %s %f', 'Delimiter',',', 'HeaderLines',1);
fclose(fid);
[prodCodeB yearB tradeValB] = deal(C{:});

%# build rows merged-keys
keysA = strcat(prodCodeA,yearA);
keysB = strcat(prodCodeB,yearB);

%# match rows
[idx1 loc1] = ismember(keysA,keysB);
[idx2 loc2] = ismember(keysB,keysA);

%# compute result for intersection of rows
tradeDiff = tradeValA(loc2(idx2)) - tradeValB(loc1(idx1))

结果相同:

tradeDiff =
      -18.566
       -17.95
       -16.51
        10.08