【发布时间】:2017-07-30 18:11:19
【问题描述】:
给定一组离散位置(例如“站点”),这些位置在某些分类方式(例如一般接近度)上成对相关并且包含本地级别的数据(例如人口规模),我希望有效地计算以相同关系为特征的成对位置上的局部级别数据之间的平均相关系数。
例如,我假设有 100 个站点,并使用值 1 到 25 随机化它们的成对关系,得到三角矩阵 relations:
import numpy as np
sites = 100
categ = 25
relations = np.random.randint(low=1, high=categ+1, size=(sites, sites))
relations = np.triu(relations) # set relation_ij = relation_ji
np.fill_diagonal(relations, 0) # ignore self-relation
我在每个站点上也有 5000 个模拟结果的重复:
sims = 5000
res = np.round(np.random.rand(sites, sims),1)
为了计算每个特定关系类别的平均成对相关性,我首先为每个关系类别i 计算每个唯一站点对j 的模拟结果res 之间的相关系数rho[j],然后取与i 关系的所有可能对的平均值:
rho_list = np.ones(categ)*99
for i in range(1, categ+1):
idr = np.transpose(np.where(relations == i)) # pairwise site indices of the same relation category
comp = np.vstack([res[idr[:,0]].ravel(), res[idr[:,1]].ravel()]) # pairwise comparisons of simulation results from the same relation category
comp_uniq = np.reshape(comp.T, (len(idr), res.shape[1], -1)) # reshape above into pairwise comparisons of simulation results between unique site pairs
rho = np.ones(len(idr))*99 # correlation coefficients of all unique site pairs of current relation category
for j in range(len(idr)): # loop through unique site pairs
comp_uniq_s = comp_uniq[j][np.all(comp_uniq!=0, axis=2)[j]].T # shorten comparisons by removing pairs with zero-valued result
rho[j] = np.corrcoef(comp_uniq_s[0], comp_uniq_s[1])[0,1]
rho_list[i-1] = np.nanmean(rho)
虽然这个脚本有效,但是一旦我增加sites = 400,那么整个计算可能需要6个多小时才能完成,这让我质疑我对数组函数的使用。表现不佳的原因是什么?以及如何优化算法?
【问题讨论】:
-
@Divakar 谢谢。我花了几天时间研究这些链接,这教会了我很多关于使用
einsum对过程进行矢量化的知识。但是,我仍然看不到如何将它们应用于我的问题,因为我需要在从中删除零值结果后计算数组对的相关系数(参见上面的脚本comp_uniq_s = comp_uniq[j][np.all(comp_uniq!=0, axis=2)[j]].T)。 -
np.corrcoef(comp_uniq_s[0], comp_uniq_s[1])[0,1]与np.corrcoef(comp_uniq[j][0], comp_uniq[j][1])[0,1]的值不同。这是故意的吗?您的 cmets 看起来好像删除零值只是为了减少计算,而不是改变结果。 -
我能找到的最大的节省时间是将
np.all(comp_uniq!=0, axis=2)[j]更改为np.all(comp_uniq[j].astype(bool), axis=-1),所以你1)不要在每次迭代时创建大布尔矩阵,2)在无用的情况下节省一些时间([0]).asytpe(bool) = ([False])时的比较。
标签: python arrays numpy optimization correlation