【问题标题】:Counting frequency of a sequence within a vector向量内序列的计数频率
【发布时间】:2012-04-11 21:07:39
【问题描述】:

假设我有一个长度为 N 的二进制向量,我正在寻找该向量中以下 16 个序列中每个序列的频率:

0000, 0001, 0010, 0011, ..., 1111

计算向量中每个序列的频率的最简单方法是什么?理想情况下,我想知道如何在 MatLab 中执行此操作。

【问题讨论】:

  • 你有什么形式的二进制向量?这些是字符串吗?这是元胞数组吗?
  • 二进制向量在MatLab中是vector形式,所以看起来像[0 0 1 1 0 1 0 ...]
  • 你关心数据的窗口大小吗?例如,假设vector = [0 0 0 0 1]。在您的问题中,这个向量是否“包含”1 个“0000”和一个“0001”,即使它们重叠......还是你会说它只包含第一个?
  • @EMS 该向量包含两者。每个序列的长度为 4,并且序列可以重叠。所以长度为 N 的向量有 N-3 个序列。

标签: matlab sequence counting


【解决方案1】:

解决此问题的一种简单方法是将二进制数转换为十进制数,然后使用histaccumarray 来计算出现次数。我首先将数组重新整形为 (N-3)×4 数组,它允许对所有计算进行矢量化。

%# make up some test data
data = [0 0 1 1 0 1 0 1 1 1 1 1 0 0 1 1];

%# reshape into a (N-3)-by-4 array
%# idx is [1 2 3 4;2 3 4 5;...]
idx = bsxfun(@plus,(1:length(data)-3)',0:3); %'# 
data = data(idx);

%# convert binary numbers to decimals
%# use matrix multiplication
decData = data * [8;4;2;1];

%# count number of occurences - possible values are 0 through 15
counts = hist(decData,0:15);

counts(1) 计算序列0 0 0 0 在列表中出现的次数。

【讨论】:

  • 这并没有考虑到序列的可能重叠,OP 指出这对于 cmets 中的这个问题是必要的。
  • @EMS:是的,这个要求是在我发布后添加的
  • @jamaicaworm:我已经更新了我的解决方案,以便将重叠序列考虑在内。
  • +1 用于bsxfunhist。虽然我认为值可能为零(0000 的序列),但你需要hist(decData, 0:15)。如所写,counts(1) 计算序列0001 出现的次数。我说的对吗?
【解决方案2】:

这些是 0x0 到 0xF 的数字,只是将它们 ++ 作为索引到大小为 0xF 的数组中。对数组元素求和,A[i]/N 是你的频率。

【讨论】:

    【解决方案3】:
    count = zeros(1,16);
    vector = [1 0 0 1 1 1 1 0 0];
    N = length(vector);
    
    for ii = 1:(N-3)
        cur_seq = vector(ii:ii+3);        % Grab the running set of four entries
        cur_num = cur_seq*[8; 4; 2; 1];   % Convert these entries to non-binary.
    
        % Update the count of the sequence that has cur_num
        % as its non-binary integer representation. Note that
        % you must use cur_num+1 as the index since Matlab is
        % 1-based, but the integers from your sequences are 0
        % through 15.
    
        count(cur_num+1) = count(cur_num+1) + 1;
    end
    

    现在count(1) 计算[0,0,0,0] 的出现次数,count(2) 计算[0,0,0,1] 的出现次数等等。

    【讨论】:

      【解决方案4】:

      让数据和块长度定义为

      x = [ 1 0 1 0 0 0 0 0 1 1];
      M = 4;
      

      那么单行就可以得到结果如下:

      result = histc(conv(x, 2.^(0:M-1), 'valid'), 0:2^M-1);
      

      在这个例子中,

      result =
           2   1   0   1   1   0   0   0   1   0   1   0   0   0   0   0
      

      意思是2出现[0 0 0 0]1出现[0 0 0 1]等等。

      这是如何工作的

      1. 2 的幂计算卷积(使用conv),以找到每个滑动长度的十进制表示-M 二进制数。
      2. 计算在步骤 1 中获得的每个数字的出现次数(使用 histc)。

      【讨论】:

        【解决方案5】:

        如果a 持有您的数据:

        c = []
        for el = a,
          c = [c, sum(a==el)];
        end
        

        这是二次的,但计数与a 的索引相同。如果您事先不知道范围,它也可以工作。

        【讨论】:

        • 我不确定这是做什么的,但它不能回答这个问题。
        • 如果 a 持有值,c 将拥有每个值的总出现次数。但也许我误解了这个问题。
        猜你喜欢
        • 1970-01-01
        • 2019-06-14
        • 2019-02-13
        • 1970-01-01
        • 2019-12-19
        • 2013-12-28
        • 1970-01-01
        相关资源
        最近更新 更多