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

如何利用Numpy内置函数高效计算数组元素的出现顺序?

用Numpy矢量化操作加速order函数

当然可以用Numpy内置函数实现无显式循环的order函数,且性能远高于纯Python循环版本。核心思路是通过排序、分组定位和累计计数的组合操作,实现完全矢量化的计算。

优化后的矢量化实现

import numpy as np

def order_np(A):
    # 将输入转换为Numpy数组(兼容列表输入)
    A = np.asarray(A)
    # 获取排序后的索引和排序后的数组
    sort_idx = np.argsort(A)
    sorted_A = A[sort_idx]
    
    # 定位每个唯一值在排序后数组中的起始位置
    diff_pos = np.where(sorted_A[1:] != sorted_A[:-1])[0] + 1
    unique_starts = np.concatenate(([0], diff_pos))
    
    # 对排序后的每个元素,找到其对应唯一值的起始位置
    start_indices = np.searchsorted(sorted_A, sorted_A, side='left')
    # 计算每个元素的出现顺序:当前位置索引 - 对应唯一值的起始索引
    counts = np.arange(len(A)) - start_indices
    
    # 将计数结果映射回原数组的顺序
    result = np.zeros_like(A)
    result[sort_idx] = counts
    return result

原理说明

  1. 排序分组:通过np.argsort将相同元素集中,方便后续批量计数。
  2. 定位起始点:用np.where找到排序后数组中相邻元素不同的位置,确定每个唯一值的起始索引。
  3. 计算顺序值:用np.searchsorted匹配每个元素所属唯一值的起始位置,当前索引减去起始位置,即得到该元素在原序列中的“出现顺序”(之前相同元素的数量)。
  4. 映射回原顺序:通过排序索引的逆操作,将计数结果放回原数组对应的位置。

性能对比

对于大规模数组(如长度100万的数组),矢量化实现的速度通常是纯Python循环的50~100倍,且内存占用更可控,避免了循环中Python对象操作的额外开销。

在scatter函数中的应用

直接替换原order函数即可,逻辑完全兼容:

def scatter(A, c):
    A = np.asarray(A)
    R = A % c
    I = c * order_np(R) + R
    B = np.full(np.max(I) + 1, -1)
    B[I] = A
    return B

该版本同样适用于多线程场景,I的生成逻辑与原实现一致,确保分散后的存储地址不会重复。

内容的提问来源于stack exchange,提问作者Changed My Name Again

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:19:58