在 Matlab 中聚合 Table 中的金融代码和日期的重复组合

Aggregate Duplicate Combinations in Table for Financial Ticker and Dates in Matlab

考虑描述 N 个金融交易的三个 N×1 向量:tickersdatesvolumes。这些向量的来源是这样的 table:

Tickers    Dates    Volumes
-------    -----    -------
TICKER1    1        200
TICKER1    1        400
TICKER1    2        100
TICKER2    1        300
...        ...      ...

来源 table 首先按代码排序,然后按日期排序。

我想合并(即计算总和)给定公司在给定日期内发生的所有交易;这意味着在给定的一天内与一家公司内的交易相对应的所有代码和日期的重复项都将被删除,而与这些交易相对应的交易量将全部加在一起并保存在唯一剩余的条目中。最终输出应如下所示:

Tickers    Dates    Volumes
-------    -----    -------
TICKER1    1        600
TICKER1    2        100
TICKER2    1        300

请注意,单独的 Dates 向量仍然包含非唯一条目,因为不同的公司(这里 TICKER1TICKER2)可以在同一天交易(这里 1);同样,Tickers 仍然包含非唯一条目,因为同一家公司(此处 TICKER1)可以在不同的日期(此处 12 进行交易。唯一性 我希望实现的是仅针对 TickersDates.

的组合 "key" 定义的

到目前为止,我的想法是按如下方式进行:

  1. 确定 volumes 中所有系数的坐标,其对应的代码 对应的日期是非唯一的。
  2. volume 中属于这一系列非唯一条目的所有系数求和,并将总和保存为非唯一系列中的第一个条目..
  3. 删除属于此非唯一系列的所有后续条目及其在 datestickers 中的相应条目。

到目前为止,我一直在尝试 [~,idx] = unique(),但没有取得太大成功。此函数 returns 仅是任何系列非唯一条目中第一个的坐标。

我的问题有两个:(1) 鉴于我的 objective 以上 "pseudocode" 在逻辑上是否正确?如果不是,那么必须如何纠正它才能按预期运行? (2) 在MATLAB中如何实现?

请注意,我将向量显示为一个 table 变量以便于展示。我正在使用三个独立的数组,并且更喜欢尽可能低级别的解决方案。

如有任何建议,我们将不胜感激!

您可以先使用 container.Map 简单地将代码映射到一个数字。然后使用映射用您的数据构建矩阵。然后,您可以使用代码 ID 和日期的唯一组合来汇总总和。最后,您重建一个新的 table 并将代码 ID 重新映射回代码名称。以下代码带有大量注释,可指导您完成整个过程。

你会需要我的超级有用custom rows2cell.m function.

% Dummy Data
T = table({'a','a','a','b'}',[1 1 2 1]', [1 1 1 1]' , [1 1 1 1]'*10);

% Find unique ticker name
C = unique( table2cell( T(:,1)));

% Create map of ticker name to num
M = containers.Map( C, 1:length(C) );
I = 1:length(C);

% Transform Table to Array
F = [cellfun( @(x) M(x), table2cell( T(:,1) ) ) table2array( T(:,2:end) )];

% Find unique combinations of ticker/day
U = unique(F(:,1:2),'rows');

% Aggregate by ticker and date
T = array2table( cell2mat( cellfun(@(x) [x sum( F( F(:,1) == x(1) & F(:,2) == x(2), 3:4 ), 1 )], rows2cell( U ), 'UniformOutput', false ) ) );

% Remap number to ticker name
T.Var1 = C(table2array( T(:,1) ) );

第18行如下,这是脚本的强大之处

T = array2table( cell2mat( cellfun(@(x) [x sum( F( F(:,1) == x(1) & F(:,2) == x(2), 3:4 ), 1 )], rows2cell( U ), 'UniformOutput', false ) ) );

我们有 ticker/day 作为单元格的独特组合,使用:

rows2cell( U )

在单元格中,x(1) 是代码,x(2) 是日期。我们想要 运行 聚合这两个参数的东西。假设这种形式,我们可以使用以下方法获取我们的逻辑掩码,以获取与此 ticker/day 组合对应的所有数据。

F(:,1) == x(1) & F(:,2) == x(2)

使用这个索引,我们可以拉取第 3 列和第 4 列:

F( F(:,1) == x(1) & F(:,2) == x(2), 3:4 )

然后在第一个方向(行)上对它们求和:

sum( F( F(:,1) == x(1) & F(:,2) == x(2), 3:4 ), 1 )

因为我们想通过连接我们的输入 (ticker/day) 和我们的数据 (col 3/4) 来构造我们新 table 的行,我们可以在 cellfun 中使用这个匿名函数:

@(x) [x sum( F( F(:,1) == x(1) & F(:,2) == x(2), 3:4 ), 1 )]

由于我们的 cellfun 将输出代表我们行的单元格向量,我们需要使用 cell2mat 将其转换为矩阵,然后使用 array2table 从矩阵转换为 table如下:

array2table( cell2mat( ... ) ).

编辑:

这是结果。输入Table:

Var1    Var2    Var3    Var4
____    ____    ____    ____
'a'     1       1       10  
'a'     1       1       10  
'a'     2       1       10  
'b'     1       1       10  

输出Table:

Var1    Var2    Var3    Var4
____    ____    ____    ____
'a'     1       2       20  
'a'     2       1       10  
'b'     1       1       10