【问题标题】:Group by one column and calculate the median for the groups in matlab按一列分组并计算matlab中组的中位数
【发布时间】:2016-02-20 14:37:47
【问题描述】:

我从 mysql 中将下表读入 matlab 元胞数组:

Nyse = fetch(conn,'SELECT ticker,date,utcsec,bid,ofr FROM HFE.Quotes where ex="N" order by utcsec,bid;');

Nyse 元胞数组包含 1000000 行。我想计算每秒的中位出价,其中第二个被记录为 utcsec 列中的字符串。我这样做是通过以下方式:

utcsec=cell2mat(Nyse(:,3));
bid=cell2mat(Nyse(:,4));
NyseBid=grpstats(bid,utcsec,{'median'});

问题在于函数 grpstats 需要大约 70 秒才能完成任务。问题是,如何优化代码以使其运行得更快?

UTCSEC 列中的示例字符串是“09:30:00”。

【问题讨论】:

  • 一百万行并不是一个微不足道的数据量。是只需要中位数还是需要grpstats计算的其他信息?
  • 我不确定我是否完全遵循数据。 utcsecbid的维度和数据类型是什么? utcsec 只是一个时间向量吗?
  • utcsec 是一个包含字符串的向量,格式如下:'09:30:00'、'09:30:00'、'09:30:01' 等等
  • bid 怎么样?是utcsecmonotonic
  • bid 是数字 2.3、2.4、4.5、4.6 等的向量。我猜 utcsec 是单调的。 utcsec 正在增加

标签: mysql matlab optimization median


【解决方案1】:

我建议您查看this question and these answers,因为这是一个高度相关的问题。

要将那个线程的结果应用到这个问题上,我会使用我写的this MEX function,它接受一个组ID 数组并提取每个组所在的行。这允许按组进行有效聚合。

据我了解,utcsec 本质上是一个 groupID,bid 是要聚合的数组。代码如下:

utcsec = Nyse(:,3);    %utcsec in this should be a cell array o fstrings
[unique_utcsec, map] = mg_getRowsWithKey(utcsec);  %call to my magic function
         %unique_utcsec contains unique strings in utcsec
         %map shows us which rows correspond to each unique second

median_bid = zeros(length(unique_utcsec), size(bid,2));

for i = 1:length(unique_utcsec)  %iterate over each utc second
    median_bid(i,:) = median(bid(map{i},:),1);  %calculate the median for that second
end

在我的测试中,这段代码比使用 grpstats 函数的 Matlab 实现要快得多。该线程中还有其他不依赖于 mex 的方法。 mex c++ 代码应该编译为:

mex -largeArrayDims mg_getRowsWithKey.cpp

然后函数 mg_getRowsWithKey 可以像任何 Matlab 函数一样被调用。 mg_getRowsWithKey 是用 C++ 编写的,使用了 map 等 STL 库。

【讨论】:

  • 如果您使用这种方法,我很想知道加速是多少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 2017-02-22
  • 1970-01-01
相关资源
最近更新 更多