web-dev-qa-db-fra.com

Pandas Correlation Groupby

En supposant que j'ai une trame de données similaire à celle ci-dessous, comment puis-je obtenir la corrélation entre 2 colonnes spécifiques, puis les regrouper par la colonne "ID"? Je crois que la méthode Pandas 'corr' trouve la corrélation entre toutes les colonnes. Si possible, je voudrais également savoir comment je pourrais trouver la corrélation 'groupby' en utilisant la fonction .agg (c'est-à-dire np. corrélatif).

Ce que j'ai:

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

Ce dont j'ai besoin:

ID  Correlation_Val1_Val2
A   0.12
B   0.22
C   0.05

Merci!

20
bsheehy

Vous avez à peu près compris toutes les pièces, il vous suffit de les combiner:

>>> 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

Dans votre cas, l'impression d'un 2x2 pour chaque ID est excessivement verbeuse. Je ne vois pas d'option pour imprimer une corrélation scalaire au lieu de la matrice entière, mais vous pouvez faire quelque chose de simple comme ceci si vous n'avez que deux variables:

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

ID       
A   Val1    0.500000
B   Val1    0.385727

Pour le cas plus général de 3+ variables

Pour 3 variables ou plus, il n'est pas simple de créer une sortie concise mais vous pouvez faire quelque chose comme ceci:

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()

Notez que si nous n'avions pas l'élément groupby, il serait simple d'utiliser une fonction triangle supérieure ou inférieure de numpy. Mais comme cet élément est présent, il n'est pas si facile de produire une sortie concise d'une manière plus élégante pour autant que je sache.

20
JohnE

Dans la réponse ci-dessus; puisque ix a été déprécié, utilisez iloc à la place avec quelques autres modifications mineures:

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

ou

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