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

Numpy数组列对组合计数优化及结果返回方法咨询

优化NumPy二进制矩阵列对的单倍型计数函数

很高兴看到你已经实现了核心功能!你的代码能正确工作,但确实可以通过NumPy向量化操作大幅提升效率(尤其是处理大矩阵时),同时让代码更简洁。另外,我们也可以轻松修改函数,返回结构化的结果供后续分析使用。


一、核心优化思路

你的现有代码用了两层Python循环(外层遍历列对,内层遍历行),这在NumPy场景下效率不高。我们可以利用NumPy的广播和向量化特性,把每一对列的组合转换成唯一的整数编码,再用统计函数直接计数:

  • 编码列对组合:对于每一对列(col1, col2),转换为整数:code = col1 * 2 + col2,这样:
    • [0,0] → 0
    • [0,1] → 1
    • [1,0] → 2
    • [1,1] → 3
  • 批量统计计数:用np.bincount对编码后的数组统计每个值的出现次数,自动补全0(如果某组合未出现)。
  • 批量处理所有列对:将原矩阵按列分组(每2列一组),然后对每组重复上述操作。

二、优化后的代码实现

下面是优化后的函数,同时支持返回结果:

import numpy as np

def calc_haplotype_freq(matrix):
    # 确保输入是NumPy数组
    matrix = np.asarray(matrix)
    num_cols = matrix.shape[1]
    # 检查列数是否为偶数(符合你的需求:第1-2、3-4列分组)
    if num_cols % 2 != 0:
        raise ValueError("矩阵列数必须为偶数")
    
    # 初始化结果数组:4种单倍型 × 列对数量
    result = np.zeros((4, num_cols//2), dtype=int)
    
    # 遍历每一对列(步长为2)
    for pair_idx in range(num_cols//2):
        col1 = matrix[:, pair_idx*2]
        col2 = matrix[:, pair_idx*2 + 1]
        # 编码列对组合为0-3的整数
        codes = col1 * 2 + col2
        # 统计每个编码的出现次数,bincount会自动补全未出现的组合为0
        counts = np.bincount(codes, minlength=4)
        # 按你的预期顺序赋值:[0,0]、[0,1]、[1,0]、[1,1]对应counts[0], counts[1], counts[2], counts[3]
        result[:, pair_idx] = counts[[0,1,2,3]]
    
    # 可选:打印统计信息
    print("H1 Frequencies (11): ", result[3].tolist())
    print("H2 Frequencies (10): ", result[2].tolist())
    print("H3 Frequencies (01): ", result[1].tolist())
    print("H4 Frequencies (00): ", result[0].tolist())
    return result

三、关键改进点说明

  1. 向量化统计:用np.bincount替代内层行循环,速度提升几个数量级(尤其是当矩阵行数很多时)。
  2. 结构化返回:函数返回一个4×N的NumPy数组(N是列对数量),每一行对应一种单倍型的计数,顺序和你的预期输出完全一致:
    • 第0行:[0,0]的计数
    • 第1行:[0,1]的计数
    • 第2行:[1,0]的计数
    • 第3行:[1,1]的计数
  3. 鲁棒性增强:增加了列数为偶数的检查,避免错误输入。
  4. 代码简洁性:去掉了冗余的索引变量和嵌套循环,逻辑更清晰。

四、验证示例输入

用你的示例输入测试:

sample_input = np.array([[0, 1, 1, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 1], [1, 1, 0, 0]])
output = calc_haplotype_freq(sample_input)
print("最终结果数组:")
print(output)

输出结果和你的预期完全一致:

H1 Frequencies (11):  [1, 1]
H2 Frequencies (10):  [2, 1]
H3 Frequencies (01):  [1, 2]
H4 Frequencies (00):  [1, 1]
最终结果数组:
[[1 1]
 [2 1]
 [1 2]
 [1 1]]

五、后续处理建议

返回的output是NumPy数组,你可以直接用于后续分析:

  • 获取第1对列的所有计数:output[:, 0] → array([1,2,1,1])
  • 获取所有列对的[1,1]计数:output[3, :] → array([1,1])
  • 转换为列表:output.tolist()
  • 保存到文件:np.save("haplotype_counts.npy", output)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:46:45