Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correlation between a pandas Series and a whole DataFrame

I have a series of values and I'm looking to compute the pearson correlation with every row of a given table.

How do I do I do that?

Example:

import pandas as pd

v = [-1, 5, 0, 0, 10, 0, -7]
v1 = [1, 0, 0, 0, 0, 0, 0]
v2 = [0, 1, 0, 0, 1, 0, 0]
v3 = [1, 1, 0, 0, 0, 0, 1]

s = pd.Series(v)
df = pd.DataFrame([v1, v2, v3], columns=['a', 'b', 'c', 'd', 'e', 'f', 'g'])

# Here I expect ot do df.corrwith(s) - but won't work

Using Series.corr() to calculate, the expected output is

-0.1666666666666666  # correlation with the first row
0.83914639167827343  # correlation with the second row
-0.35355339059327379 # correlation with the third row
like image 397
bluesummers Avatar asked Jan 23 '17 12:01

bluesummers


2 Answers

You need same index of Series as columns of DataFrame for align Series by DataFrame and add axis=1 in corrwith for row-wise correlation:

s1 = pd.Series(s.values, index=df.columns)
print (s1)
a    -1
b     5
c     0
d     0
e    10
f     0
g    -7
dtype: int64

print (df.corrwith(s1, axis=1))
0   -0.166667
1    0.839146
2   -0.353553
dtype: float64

print (df.corrwith(pd.Series(v, index=df.columns), axis=1))
0   -0.166667
1    0.839146
2   -0.353553
dtype: float64

EDIT:

You can specify columns and use subset:

cols = ['a','b','e']

print (df[cols])
   a  b  e
0  1  0  0
1  0  1  1
2  1  1  0

print (df[cols].corrwith(pd.Series(v, index=df.columns), axis=1))
0   -0.891042
1    0.891042
2   -0.838628
dtype: float64
like image 107
jezrael Avatar answered Nov 09 '22 16:11

jezrael


This might be useful to those concerned with performance. I have found this runs in half the time compared to pandas corrwith.

Your data:

import pandas as pd
v = [-1, 5, 0, 0, 10, 0, -7]
v1 = [1, 0, 0, 0, 0, 0, 0]
v2 = [0, 1, 0, 0, 1, 0, 0]
v3 = [1, 1, 0, 0, 0, 0, 1]    
df = pd.DataFrame([v1, v2, v3], columns=['a', 'b', 'c', 'd', 'e', 'f', 'g'])

The solution (note that v is not transformed into a series):

from scipy.stats.stats import pearsonr
s_corrs = df.apply(lambda x: pearsonr(x.values, v)[0], axis=1)
like image 2
Reimar Avatar answered Nov 09 '22 16:11

Reimar