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

将仅含0、0.5、1、1.5的列表高效转换为PMF的最优方法

高效生成固定取值列表的概率质量函数(PMF)

我有多个仅包含0、0.5、1、1.5的列表,希望将每个列表高效转换为概率质量函数(PMF)。例如列表[0.5, 0.5, 1, 1.5]对应的PMF为[0, 0.5, 0.25, 0.25]。由于需要多次处理这类大型列表,若能避免循环则最佳,请问实现这一需求的最高效方法是什么?

当前低效实现

以下是我当前的实现方案,我认为这种方式效率低下且不够简洁:

def get_distribution(samplemodes1):
    
    n, bin_edges = np.histogram(samplemodes1, bins = 9)
    totalcount = np.sum(n)
    bin_probability = n / totalcount
    bins_per_point = np.fmin(np.digitize(samplemodes1, bin_edges), len(bin_edges)-1)
    probability_perpoint = [bin_probability[bins_per_point[i]-1] for i in range(len(samplemodes1))] 
    
    counts = Counter(samplemodes1)
    total = sum(counts.values())
    
    probability_mass = {k:v/total for k,v in counts.items()}
    #print(probability_mass)
    
    key_values = {}
    
    if(0 in probability_mass):
        key_values[0] = probability_mass.get(0)
    else:
        key_values[0] = 0
    if(0.5 in probability_mass):
        key_values[0.5] = probability_mass.get(0.5)
    else:
        key_values[0.5] = 0
    if(1 in probability_mass):
        key_values[1] = probability_mass.get(1)
    else:
        key_values[1] = 0
    if(1.5 in probability_mass):
        key_values[1.5] = probability_mass.get(1.5)  
    else:
        key_values[1.5] = 0
        
        
    distribution = list(key_values.values())
    return distribution

高效实现方案

方法一:Numpy bincount映射法(性能最优)

将固定浮点值映射为整数索引,利用np.bincount一次性统计所有频次,全程向量化操作,无循环,处理大型数组速度最快:

import numpy as np

def get_pmf(arr):
    arr_np = np.array(arr)
    # 将0→0、0.5→1、1→2、1.5→3映射为整数索引
    indices = (arr_np * 2).astype(np.int32)
    # 统计每个索引的出现次数,minlength确保覆盖4个取值
    counts = np.bincount(indices, minlength=4)
    # 计算概率并转为列表
    return (counts / len(arr_np)).tolist()

方法二:简化Counter实现(标准库方案)

利用Counter.get()的默认值特性,直接按固定顺序生成PMF,删除冗余的条件判断:

from collections import Counter

def get_pmf(arr):
    count_dict = Counter(arr)
    total = len(arr)
    # 按固定取值顺序生成概率列表,缺失值默认取0
    return [count_dict.get(val, 0) / total for val in [0, 0.5, 1, 1.5]]

方法三:Numpy count_nonzero法

直接统计每个固定值的出现次数,逻辑直观,同样无循环:

import numpy as np

def get_pmf(arr):
    arr_np = np.array(arr)
    total = len(arr_np)
    return [
        np.count_nonzero(arr_np == 0) / total,
        np.count_nonzero(arr_np == 0.5) / total,
        np.count_nonzero(arr_np == 1) / total,
        np.count_nonzero(arr_np == 1.5) / total
    ]

性能说明

  • 处理百万级以上的大型列表时,Numpy bincount方法效率最高,比原始实现快数十倍;
  • 原始实现中冗余的直方图计算代码完全可以删除,仅保留Counter相关逻辑也能大幅提升效率;
  • 所有高效方案均避免了显式循环,充分利用Python/Numpy的内部优化机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:50:30