You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB中求子集对应原向量索引的高效实现方案问询

Optimizing item2ind for Large Datasets with Vectorized Operations

Hey there! Let's tackle this item2ind optimization problem. I've worked through a fully vectorized approach that should drastically outperform the serial or naive parfor versions, especially for large-scale inputs like your 100k-row test case.

Core Problem Recap

We need to map each element in the item matrix to the first unused occurrence of that value in the vector t. For example:

  • Given t = [1 1 3 2 2 2 3]
  • item = [2 3 1] maps to [4 3 1] (first unused 2, then first unused 3, then first unused 1)
  • item = [2 1 2] maps to [4 1 5] (first 2, first 1, then the next unused 2)

We also need to error out if item contains more instances of a value than exist in t.

Vectorized Implementation Approach

The key idea is to preprocess t to track all indices for each unique value, then compute how many times each value appears in every row of item, and finally map those counts directly to the precomputed indices. Here's the code:

function ind = item2ind_new(item, t)
    % Step 1: Preprocess t to get ordered indices for each unique value
    [unique_vals, ~, t_val_idx] = unique(t, 'stable');
    val_indices = accumarray(t_val_idx, 1:length(t), [], @(x) {x});
    val_counts = cellfun(@length, val_indices);
    
    % Step 2: Validate item elements exist in t
    [item_val_idx, is_found] = ismember(item, unique_vals, 'stable');
    if ~all(is_found(:))
        error('item contains elements not present in t');
    end
    
    % Step 3: Calculate occurrence count of each value per row in item
    row_ids = repmat(1:size(item,1), size(item,2), 1)';
    pair = [row_ids(:), item_val_idx(:)];
    [~, ~, pair_idx] = unique(pair, 'rows', 'stable');
    counts = accumarray(pair_idx, 1, [], @cumsum);
    counts = reshape(counts, size(item));
    
    % Step 4: Check for insufficient occurrences in t
    over_count = counts > val_counts(item_val_idx);
    if any(over_count(:))
        error('item contains elements with insufficient occurrences in t');
    end
    
    % Step 5: Map counts to the precomputed indices from t
    start_pos = cumsum([0; val_counts(:)]);
    global_idx = start_pos(item_val_idx) + counts - 1;
    all_indices = cell2mat(val_indices');
    ind = reshape(all_indices(global_idx), size(item));
end

Breakdown of Each Step

  1. Preprocess t:

    • We use unique('stable') to keep the order of first occurrences intact.
    • accumarray collects all indices for each unique value, preserving their order in t (critical for picking the first unused instance).
  2. Validate item:

    • ismember checks that all elements in item exist in t—no invalid values slip through.
  3. Count Occurrences per Row:

    • We create unique pairs of (row number, value index) to track how many times each value has appeared up to each position in the row.
    • accumarray with cumsum efficiently computes these running counts without loops.
  4. Check for Overflows:

    • We compare the occurrence counts in item to the total available instances in t—if any count exceeds the available, we throw an error.
  5. Map to Indices:

    • We flatten the precomputed index lists into a single array, then calculate the linear index for each element in item based on its occurrence count. This lets us look up all indices in one vectorized operation.

Performance Testing

Using your provided test case:

t = 1:10; % 10个唯一值
t = repmat(t,1,5); % 每个值重复5次的无序向量
nlp = 100000; % item行数
[~,p] = sort(rand(nlp,length(t)),2); % 100000个随机排列
item = t(p); % 转换为item矩阵
item = item(:,1:30); % 截取子集
tic;ind = item2ind(item,t);toc % 原函数计时
tic;ind_ = item2ind_new(item,t);toc % 新函数计时
isequal(ind,ind_) % 结果对比

You should see a massive speedup—this vectorized approach avoids per-row loops entirely, leveraging Matlab's optimized array operations. The isequal check will confirm the results match exactly with the original function.

内容的提问来源于stack exchange,提问作者michal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:18:22