如果另一个 n*n 的值具有特定值 (Python),则仅显示 n*n 矩阵的值
Only show value of n*n matrix if value from another n*n has a certain value (Python)
所以我目前正在尝试为我拥有的一些数据计算 Pearson 的 R 值和 p 值。这是通过以下代码完成的:
import numpy as np
from scipy.stats import pearsonr, betai
from pandas import DataFrame
import seaborn as sns
import matplotlib.pyplot as plt
def corrcoef(matrix): #function that calculates the Pearson's R and p-value
r = np.corrcoef(matrix)
rf = r[np.triu_indices(r.shape[0], 1)]
df = matrix.shape[1] - 2
ts = rf * rf * (df / (1 - rf * rf))
pf = betai(0.5 * df, 0.5, df / (df + ts))
p = np.zeros(shape=r.shape)
p[np.triu_indices(p.shape[0], 1)] = pf
p[np.tril_indices(p.shape[0], -1)] = pf
p[np.diag_indices(p.shape[0])] = np.ones(p.shape[0])
return r, p
data = np.loadtxt('corr-data.txt') #data matrix loaded
sig_lvl = 0.05 #significance level
r_mat, p_mat = corrcoef(data) #use function on data and put the answers in two different matrices
df_rmat = DataFrame(r_mat, columns=Index, index=Index) #make data readable for the seaborn package
df_pmat = DataFrame(p_mat, columns=Index, index=Index)
r_mat[abs(r_mat) <= .90] = np.nan #if the R-value matrix elements are under 0.90, don't show them - make them NaN.
p_mat[abs(p_mat) >= sig_lvl] = np.nan #this is probably the issue.
mask_pmat = np.zeros_like(p_mat)
mask_pmat[np.tril_indices_from(mask_pmat)] = True #only showing the upper triangle of the values since it's symmetrical in the diagonal
sns.plt.subplot(1,2,2)
ax_pmat = sns.heatmap(np.around(df_pmat, decimals=2), annot=True, mask = mask_pmat) #subplot sequence for the p-value matrix only
sns.plt.show()
它可能不是最佳代码,但目前它可以按预期工作。使用 seaborn 包,如果它们足够高(> = 0.95)或具有正确的显着性水平,我会得到 heat/colormap 个不同的值,并且只有上三角。但是,我实际上想做的是只显示第一个图中表示的那些 R 值的 p 值。小于 0.95 的值仅由 NaN 代替,并且在热图中没有颜色。因此,如果表示 R 值矩阵中的值,则仅应表示 p 值矩阵中的值。
这可以做到,还是...?
如果有什么不清楚的地方,请告诉我。然后我会尝试进一步解释。
提前致谢
我想你的意思是这样的:
p_mat[r_mat < 0.95] = np.nan
之所以有效,是因为 p
和 r
是相同的形状。它会进入您的代码而不是:
if r_mat[abs(r_mat) <= .90] == np.nan:
p_mat = np.nan
请注意,如果将 NaN
与某个值进行比较,结果始终为假。
所以我目前正在尝试为我拥有的一些数据计算 Pearson 的 R 值和 p 值。这是通过以下代码完成的:
import numpy as np
from scipy.stats import pearsonr, betai
from pandas import DataFrame
import seaborn as sns
import matplotlib.pyplot as plt
def corrcoef(matrix): #function that calculates the Pearson's R and p-value
r = np.corrcoef(matrix)
rf = r[np.triu_indices(r.shape[0], 1)]
df = matrix.shape[1] - 2
ts = rf * rf * (df / (1 - rf * rf))
pf = betai(0.5 * df, 0.5, df / (df + ts))
p = np.zeros(shape=r.shape)
p[np.triu_indices(p.shape[0], 1)] = pf
p[np.tril_indices(p.shape[0], -1)] = pf
p[np.diag_indices(p.shape[0])] = np.ones(p.shape[0])
return r, p
data = np.loadtxt('corr-data.txt') #data matrix loaded
sig_lvl = 0.05 #significance level
r_mat, p_mat = corrcoef(data) #use function on data and put the answers in two different matrices
df_rmat = DataFrame(r_mat, columns=Index, index=Index) #make data readable for the seaborn package
df_pmat = DataFrame(p_mat, columns=Index, index=Index)
r_mat[abs(r_mat) <= .90] = np.nan #if the R-value matrix elements are under 0.90, don't show them - make them NaN.
p_mat[abs(p_mat) >= sig_lvl] = np.nan #this is probably the issue.
mask_pmat = np.zeros_like(p_mat)
mask_pmat[np.tril_indices_from(mask_pmat)] = True #only showing the upper triangle of the values since it's symmetrical in the diagonal
sns.plt.subplot(1,2,2)
ax_pmat = sns.heatmap(np.around(df_pmat, decimals=2), annot=True, mask = mask_pmat) #subplot sequence for the p-value matrix only
sns.plt.show()
它可能不是最佳代码,但目前它可以按预期工作。使用 seaborn 包,如果它们足够高(> = 0.95)或具有正确的显着性水平,我会得到 heat/colormap 个不同的值,并且只有上三角。但是,我实际上想做的是只显示第一个图中表示的那些 R 值的 p 值。小于 0.95 的值仅由 NaN 代替,并且在热图中没有颜色。因此,如果表示 R 值矩阵中的值,则仅应表示 p 值矩阵中的值。
这可以做到,还是...?
如果有什么不清楚的地方,请告诉我。然后我会尝试进一步解释。
提前致谢
我想你的意思是这样的:
p_mat[r_mat < 0.95] = np.nan
之所以有效,是因为 p
和 r
是相同的形状。它会进入您的代码而不是:
if r_mat[abs(r_mat) <= .90] == np.nan:
p_mat = np.nan
请注意,如果将 NaN
与某个值进行比较,结果始终为假。