Показывать значение матрицы n * n только в том случае, если значение из другого n * n имеет определенное значение (Python)

#python #numpy #matplotlib #scipy #seaborn

#python #numpy #matplotlib #scipy #seaborn

Вопрос:

Итак, в настоящее время я пытаюсь вычислить 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) или имеют правильный уровень значимости, и только верхний треугольник. Однако то, что я действительно хотел бы сделать, это показать значение p только для тех R-значений, которые представлены на первом графике. Значения, которые меньше 0,95, просто заменяются на NaN и не имеют цвета на тепловой карте. Таким образом, должны быть представлены только значения в матрице p-значений, если представлены значения в матрице R-значений.

Можно ли это сделать или …?

И, пожалуйста, дайте мне знать, если что-то неясно. Затем я попытаюсь подробнее объяснить.

Заранее спасибо

Комментарии:

1. Я думаю, вам нужна логическая переменная того же размера, что и ваша r-матрица. Было бы полезно, если бы вы сделали свой минимальный рабочий пример более минимальным.

Ответ №1:

Я думаю, что вы говорите следующее:

 p_mat[r_mat < 0.95] = np.nan
  

Это работает, потому p что и r имеют одинаковую форму. Это вошло бы в ваш код вместо:

 if r_mat[abs(r_mat) <= .90] == np.nan:
    p_mat = np.nan
  

Обратите внимание, что если вы сравниваете NaN со значением, результат всегда false .

Комментарии:

1. Привет, и спасибо за ваш ответ. Я попытался очистить свой код и теперь показываю только необходимые вещи (надеюсь). Сделанное мной утверждение if на самом деле не предназначалось для включения, поскольку оно не сработало 🙂 Однако ваше предложение, похоже, тоже не сработало. В принципе, это имеет смысл для меня, но, к сожалению, это не сработало.

2. Ах, так я понял это. Я просто изменил две строки r_mat / p_mat на: p_mat[abs (p_mat)> = 0.05] = np.nan p_mat[abs (r_mat) <= 0.90] = np.nan r_mat[abs (r_mat) <= 0.90] = np.nan и тогда это сработало. Еще раз, спасибо за вашу помощь 🙂