考虑描述N个金融交易的三个N乘1向量:tickers
,dates
和volumes
。这些载体的来源是这样的表:
Tickers Dates Volumes
------- ----- -------
TICKER1 1 200
TICKER1 1 400
TICKER1 2 100
TICKER2 1 300
... ... ...
源表首先按代码排序,其次按日期排序。
我想合并(即计算)给定公司在给定日期内发生的所有交易;意味着消除了与给定日期内一家公司内的交易相对应的所有代码和日期的副本,而与这些交易相对应的卷全部加在一起并保存在唯一的剩余条目中。最终输出应如下所示:
Tickers Dates Volumes
------- ----- -------
TICKER1 1 600
TICKER1 2 100
TICKER2 1 300
请注意,仅Dates
向量仍包含非唯一条目,因为不同的公司(此处TICKER1
和TICKER2
)可以在同一天进行交易(此处为1
) ;同样,Tickers
仍然包含非唯一条目,因为同一公司(此处TICKER1
)可以在不同日期进行交易(此处为1
和2
。 uniqueness 我希望实现仅针对Tickers
和Dates
的组合“关键字”进行定义。
到目前为止,我的想法一直如下:
volumes
中所有系数的坐标,相应的代码和对应的日期是非唯一的。volume
中属于此系列非唯一条目的所有系数求和,并将总和保存为非唯一系列中的第一个条目.. dates
和tickers
中的相应条目。到目前为止,我一直在试验[~,idx] = unique()
,但没有取得多大成功。此函数仅返回任何一系列非唯一条目中第一个的坐标。
我的问题是双重的:(1)鉴于我的目标是上面的“伪代码”在逻辑上是否正确?如果不是,为了表现得如何,必须如何纠正? (2)如何在MATLAB中实现?
请注意,我将向量显示为一个表变量,以便于演示。我正在使用三个独立的阵列,并且更喜欢最低级别的解决方案。
任何建议都将不胜感激!
答案 0 :(得分:1)
您可以使用container.Map
将代码首先映射到数字。然后使用映射来构建包含数据的矩阵。然后,您可以使用股票代码ID和日期的唯一组合来汇总总和。最后,您重新构建一个新表并将股票代码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 ) ) );
我们使用独特的自动收报机/天组合作为单元格:
rows2cell( U )
在单元格中,x(1)
是代码,x(2)
是日期。我们希望运行将在这两个参数上聚合的东西。假设有这种形式,我们可以使用以下内容获取逻辑掩码,以获得与此自动收报机/日组合相对应的所有数据。
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)来构造新表的行,我们可以在cellfun中使用这个匿名函数:
@(x) [x sum( F( F(:,1) == x(1) & F(:,2) == x(2), 3:4 ), 1 )]
由于我们的cellfun将输出表示行的单元格向量,我们需要使用cell2mat
将其转换为矩阵,然后使用array2table
从矩阵转换为表格,如下所示:
array2table( cell2mat( ... ) ).
修改强>
这是结果。输入表:
Var1 Var2 Var3 Var4
____ ____ ____ ____
'a' 1 1 10
'a' 1 1 10
'a' 2 1 10
'b' 1 1 10
输出表:
Var1 Var2 Var3 Var4
____ ____ ____ ____
'a' 1 2 20
'a' 2 1 10
'b' 1 1 10