如何在Numpy二维数组的每一对列上执行指定函数?
嘿,看来你需要对Numpy数组里的每一对列执行自定义函数对吧?看你给出的基因型数组(元素是1、0、-1,应该是表示不同的等位基因编码或者缺失值),我给你整理几个实用的方案,从简单直观到高效向量化都有:
方法1:双重循环遍历列对(直观易上手)
如果你的数组是g,可以直接遍历所有i≤j的列对——这样能避免重复计算(比如列0和列1的结果和列1和列0通常是对称的)。举个例子,假设我们要计算两列基因型的匹配率:
import numpy as np # 自定义函数:计算两列基因型的匹配比例 def genotype_similarity(col1, col2): return np.mean(col1 == col2) # 获取数组的列数 n_cols = g.shape[1] # 初始化对称结果矩阵 result_matrix = np.zeros((n_cols, n_cols)) for i in range(n_cols): for j in range(i, n_cols): if i == j: # 自己和自己的相似度设为1 result_matrix[i,j] = 1.0 else: sim = genotype_similarity(g[:, i], g[:, j]) result_matrix[i,j] = sim result_matrix[j,i] = sim # 对称赋值,避免重复计算 print(result_matrix)
这个方法逻辑直白,新手也能快速理解,不过如果你的列数特别多(比如上千列),速度会稍慢。
方法2:用itertools生成列对(写法更简洁)
用itertools.combinations可以自动生成所有不重复的列对,代码会更清爽:
import itertools for i, j in itertools.combinations(range(n_cols), 2): sim = genotype_similarity(g[:, i], g[:, j]) result_matrix[i,j] = sim result_matrix[j,i] = sim
本质和方法1效率差不多,但代码更简洁,适合列数不是特别夸张的场景。
方法3:向量化操作(处理大规模数据首选)
如果你的自定义函数可以拆解成Numpy的元素级操作,那用向量化方法能大幅提升速度——完全没有Python循环,靠Numpy的底层C实现加速。还是以计算匹配率为例:
# 转置数组,变成(列数, 行数)的形状,方便广播运算 g_T = g.T # 广播计算每一列和其他所有列的匹配次数,得到(n_cols, n_cols)的矩阵 matches = (g_T[:, None, :] == g_T[None, :, :]).sum(axis=2) # 除以总行数,得到相似度矩阵 similarity_matrix = matches / g.shape[0]
这个方法处理上万列都不在话下,前提是你的自定义函数能适配向量化逻辑。如果函数涉及复杂条件(比如要忽略缺失值),也可以调整:
# 假设-1是缺失值,计算时忽略这些位置 valid_mask = (g_T[:, None, :] != -1) & (g_T[None, :, :] != -1) # 只统计有效位置的匹配数 matches = (g_T[:, None, :] == g_T[None, :, :]) & valid_mask # 计算有效匹配比例,无有效数据的位置设为NaN similarity_matrix = matches.sum(axis=2) / valid_mask.sum(axis=2) similarity_matrix[valid_mask.sum(axis=2) == 0] = np.nan
内容的提问来源于stack exchange,提问作者ksw
相关产品推荐
相关产品推荐

