Группа корреляции панд

Предполагая, что у меня есть фрейм данных, подобный приведенному ниже, как мне получить корреляцию между двумя конкретными столбцами, а затем сгруппировать их по столбцу «ID»? Я считаю, что метод Pandas 'corr' находит корреляцию между всеми столбцами. Если возможно, я также хотел бы знать, как я могу найти корреляцию groupby с помощью функции .agg (т.е. np.correlate).

Что у меня есть:

ID  Val1    Val2    OtherData   OtherData
A   5       4       x           x
A   4       5       x           x
A   6       6       x           x
B   4       1       x           x
B   8       2       x           x
B   7       9       x           x
C   4       8       x           x
C   5       5       x           x
C   2       1       x           x

Что мне нужно:

ID  Correlation_Val1_Val2
A   0.12
B   0.22
C   0.05

Спасибо!


person bsheehy    schedule 11.03.2015    source источник


Ответы (3)


Вы в значительной степени разобрались со всеми частями, просто нужно их объединить:

>>> df.groupby('ID')[['Val1','Val2']].corr()

             Val1      Val2
ID                         
A  Val1  1.000000  0.500000
   Val2  0.500000  1.000000
B  Val1  1.000000  0.385727
   Val2  0.385727  1.000000

В вашем случае распечатка 2x2 для каждого идентификатора чрезмерно многословна. Я не вижу возможности распечатать скалярную корреляцию вместо всей матрицы, но вы можете сделать что-то простое, например, если у вас есть только две переменные:

>>> df.groupby('ID')[['Val1','Val2']].corr().iloc[0::2,-1]

ID       
A   Val1    0.500000
B   Val1    0.385727

Для более общего случая 3+ переменных

Для 3 или более переменных создать краткий вывод непросто, но вы можете сделать что-то вроде этого:

groups = list('Val1', 'Val2', 'Val3', 'Val4')
df2 = pd.DataFrame()
for i in range( len(groups)-1): 
    df2 = df2.append( df.groupby('ID')[groups].corr().stack()
                        .loc[:,groups[i],groups[i+1]:].reset_index() )

df2.columns = ['ID', 'v1', 'v2', 'corr']
df2.set_index(['ID','v1','v2']).sort_index()

Обратите внимание: если бы у нас не было элемента groupby, было бы просто использовать функцию верхнего или нижнего треугольника из numpy. Но поскольку этот элемент присутствует, насколько я могу судить, не так-то просто произвести сжатый вывод более элегантным образом.

person JohnE    schedule 11.03.2015
comment
Как мне изменить это на «Rolling_corr ()», чтобы скользящая корреляция рассчитывалась каждые 10 дней? - person bsheehy; 12.03.2015
comment
Это отличный ответ. Тот факт, что для чего-то такого простого означает необходимость возиться с .ilocs, - это одна из вещей, которая действительно расстраивает меня в pandas; если я хочу создать большой конвейер обработки научных данных, у меня возникает ощущение, что все скреплено зубной пастой. - person Cai; 25.09.2018

Еще одно простое решение:

df.groupby('ID')[['Val1','Val2']].corr().unstack().iloc[:,1]
person VovaM    schedule 26.11.2019

В приведенном выше ответе; поскольку ix был обесценен, используйте iloc с некоторыми другими незначительными изменениями:

df.groupby('ID')[['Val1','Val2']].corr().iloc[0::2][['Val2']] # to get pandas DataFrame

or

df.groupby('ID')[['Val1','Val2']].corr().iloc[0::2]['Val2'] # to get pandas Series
person Ravaging Care    schedule 25.07.2018
comment
Ах, как странно, я фактически сделал ту же правку одновременно с вами. Мы сделали это немного по-другому, поэтому я просто оставлю свой как есть и добавлю +1 к этому. - person JohnE; 25.07.2018