#python #python-3.x #pandas
Вопрос:
У меня есть correlation matrix
pandas
фрейм данных, который выглядит следующим образом:
import pandas as pd
foo = pd.DataFrame({'vars': ['col_a', 'col_b', 'col_c', 'col_d'],
'col_a': [1, 0.9, 0.04, 0.03],
'col_b': [0.9,1,0.05,0.03],
'col_c': [0.04, 0.05, 1, -0.04],
'col_d': [0.03, 0.03, -0.04,1]})
Я хотел бы получить все уникальные «пары», которые по абсолютному значению имеют корреляцию выше определенной threshold
и исключают самокорреляцию
Итак, если порог есть 0.8
, я должен получить что-то вроде этого:
[('col_a', 'col_b')]
Есть идеи, как я мог бы это сделать ?
Комментарии:
1. вы хотите иметь уникальные пары? а самокорреляция?
2. Возможны ли ожидаемые изменения в будущем? Потому что принятое решение не совпадает.
3. Хорошо, тогда супер. Счастливого кодирования.
4. Да, теперь я вижу вашу правку 🙂
5. удалено решение, лучше в будущем не менять вопрос, потому что ответы не совпадают. Лучше всего опубликовать новый вопрос, если он быстро изменится, как здесь.
Ответ №1:
Вы можете установить ‘vars’ в качестве индекса stack
и использовать выходные данные для нарезки:
pairs = foo.set_index('vars').stack()
pairs[pairs.abs().gt(0.8)]
выход:
vars
col_a col_a 1.0
col_b 0.9
col_b col_a 0.9
col_b 1.0
col_c col_c 1.0
col_d col_d 1.0
Как список:
pairs = foo.set_index('vars').stack()
list(pairs[pairs.gt(0.8)].index)
[('col_a', 'col_a'), ('col_a', 'col_b'), ('col_b', 'col_a'), ('col_b', 'col_b'), ('col_c', 'col_c'), ('col_d', 'col_d')]
Если вы хотите получить только уникальные пары (например, B vs A == A vs B) и отказаться от самокорреляции (например, A vs A), используйте эту альтернативу.
np.triu
позволяет сохранить только один из треугольников в корреляционной матрице, а k
параметр позволяет сдвинуть диагональ ( k=0
сохраняет диагональ, k=1
удаляет диагональ, таким образом, если вы хотите сохранить самокорреляцию, используйте k=0
)
import numpy as np
foo = foo.set_index('vars')
pairs = foo.where(np.triu(foo, k=1).astype(bool)).stack()
list(pairs[pairs.abs().gt(0.8)].index)
выход:
[('col_a', 'col_b')]
Комментарии:
1. для решения без самокорреляции
foo = foo.set_index('vars')
необходимо добавить после импорта numpy или заменитьfoo
наfoo.set_index('vars')
2. Да, спасибо @quant, я, видимо, забыл его вставить 😉
Ответ №2:
Вы можете использовать петлю. Попробуй это. Во-первых, отбросьте столбец vars и возьмите корреляции.
foo = foo.drop('vars', axis = 1).corr()
Затем с помощью этого цикла возьмите корреляции между условиями. 0,8 и 0,99 (чтобы избежать самого себя)
a = []
b = []
for i in foo.columns:
for ii in range(len(foo.columns)):
if (foo[i].iloc[ii] > 0.8) and (foo[i].iloc[ii] < 0.99):
a.append(i)
b.append(foo[i].iloc[ii])
Вы можете просмотреть функции и исправления со списком a и b.
Тогда, если вы хотите визуализировать;
df = (foo > 0.95 ) amp; (foo < 1)
df.applymap(lambda x: True if x else np.nan).dropna(how = 'all', axis = 1).dropna(how = 'all').fillna('-')