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

如何不使用for循环获取numpy数组中每个唯一键的最小值?

无循环实现numpy按键分组取最小值(高效方案)

针对你提出的需求——无需循环,快速获取每个唯一键对应的最小值(多数键唯一的场景),以下是几种可行的高效实现方案:

方案1:Numpy原生排序+reduceat(通用高效)

通过排序将相同键的元素聚合,再用reduceat批量计算最小值,避免显式循环,时间复杂度为O(n log n),在多数键唯一的场景下远优于二次方复杂度的循环方案。

import numpy as np

keys = np.array([1, 2, 2, 3, 3, 2])
vals = np.array([0.2, 0.6, 0.8, 0.4, 0.9, 0.3])

# 按键排序,聚合相同键的元素
sorted_idx = np.argsort(keys)
sorted_keys = keys[sorted_idx]
sorted_vals = vals[sorted_idx]

# 定位唯一键的起始分割点
split_pos = np.concatenate(([0], np.where(sorted_keys[1:] != sorted_keys[:-1])[0] + 1))

# 批量计算分组最小值
unique_keys = sorted_keys[split_pos]
min_values = np.min.reduceat(sorted_vals, split_pos)

# 结果可按需转为字典或保留数组形式
result = dict(zip(unique_keys, min_values))
print(result)  # 输出: {1: 0.2, 2: 0.3, 3: 0.4}

方案2:整数键专属优化(O(n)时间复杂度)

如果你的键是整数类型且数值范围可控,可以利用Numpy的索引广播特性直接更新最小值,完全无排序开销,是速度最快的方案:

import numpy as np

keys = np.array([1, 2, 2, 3, 3, 2])
vals = np.array([0.2, 0.6, 0.8, 0.4, 0.9, 0.3])

# 初始化最小值数组为无穷大
max_key = keys.max()
min_vals = np.full(max_key + 1, np.inf)

# 无循环更新每个键对应的最小值
np.minimum.at(min_vals, keys, vals)

# 提取有效结果
unique_keys = np.unique(keys)
result_vals = min_vals[unique_keys]

result = dict(zip(unique_keys, result_vals))
print(result)  # 输出: {1: 0.2, 2: 0.3, 3: 0.4}

方案3:Pandas Groupby(代码简洁易读)

若不依赖纯Numpy实现,Pandas的groupby底层做了优化,代码简洁且在大数据量下效率可观,适合快速开发:

import pandas as pd
import numpy as np

keys = np.array([1, 2, 2, 3, 3, 2])
vals = np.array([0.2, 0.6, 0.8, 0.4, 0.9, 0.3])

df = pd.DataFrame({"key": keys, "value": vals})
result = df.groupby("key")["value"].min().to_dict()
print(result)  # 输出: {1: 0.2, 2: 0.3, 3: 0.4}

方案选择建议

  • 键为整数且范围小:优先选方案2,O(n)时间复杂度,速度最快
  • 键类型无限制、追求纯Numpy实现:选方案1,平衡通用性和效率
  • 追求代码简洁、快速实现:选方案3,Pandas的优化足够应对多数场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:26:15