J'essaie de calculer une matrice de corrélation de plusieurs valeurs. Ces valeurs incluent certaines valeurs "nan". J'utilise numpy.corrcoef. Pour l'élément (i, j) de la matrice de corrélation de sortie, j'aimerais que la corrélation soit calculée en utilisant toutes les valeurs qui existent pour la variable i et la variable j.
Voici ce que j'ai maintenant:
In[20]: df_counties = pd.read_sql("SELECT Median_Age, Rpercent_2008, overall_LS, population_density FROM countyVotingSM2", db_eng)
In[21]: np.corrcoef(df_counties, rowvar = False)
Out[21]:
array([[ 1. , nan, nan, -0.10998411],
[ nan, nan, nan, nan],
[ nan, nan, nan, nan],
[-0.10998411, nan, nan, 1. ]])
Trop de nan's :(
L'une des principales caractéristiques de pandas
est d'être compatible avec NaN
. Pour calculer la matrice de corrélation, il suffit d'appeler df_counties.corr()
. Voici un exemple pour démontrer que df.corr()
est NaN
tolérant alors que np.corrcoef
n'est pas.
import pandas as pd
import numpy as np
# data
# ==============================
np.random.seed(0)
df = pd.DataFrame(np.random.randn(100,5), columns=list('ABCDE'))
df[df < 0] = np.nan
df
A B C D E
0 1.7641 0.4002 0.9787 2.2409 1.8676
1 NaN 0.9501 NaN NaN 0.4106
2 0.1440 1.4543 0.7610 0.1217 0.4439
3 0.3337 1.4941 NaN 0.3131 NaN
4 NaN 0.6536 0.8644 NaN 2.2698
5 NaN 0.0458 NaN 1.5328 1.4694
6 0.1549 0.3782 NaN NaN NaN
7 0.1563 1.2303 1.2024 NaN NaN
8 NaN NaN NaN 1.9508 NaN
9 NaN NaN 0.7775 NaN NaN
.. ... ... ... ... ...
90 NaN 0.8202 0.4631 0.2791 0.3389
91 2.0210 NaN NaN 0.1993 NaN
92 NaN NaN NaN 0.1813 NaN
93 2.4125 NaN NaN NaN 0.2515
94 NaN NaN NaN NaN 1.7389
95 0.9944 1.3191 NaN 1.1286 0.4960
96 0.7714 1.0294 NaN NaN 0.8626
97 NaN 1.5133 0.5531 NaN 0.2205
98 NaN NaN 1.1003 1.2980 2.6962
99 NaN NaN NaN NaN NaN
[100 rows x 5 columns]
# calculations
# ================================
df.corr()
A B C D E
A 1.0000 0.2718 0.2678 0.2822 0.1016
B 0.2718 1.0000 -0.0692 0.1736 -0.1432
C 0.2678 -0.0692 1.0000 -0.3392 0.0012
D 0.2822 0.1736 -0.3392 1.0000 0.1562
E 0.1016 -0.1432 0.0012 0.1562 1.0000
np.corrcoef(df, rowvar=False)
array([[ nan, nan, nan, nan, nan],
[ nan, nan, nan, nan, nan],
[ nan, nan, nan, nan, nan],
[ nan, nan, nan, nan, nan],
[ nan, nan, nan, nan, nan]])
Cela fonctionnera, en utilisant le module masqué numpy
:
import numpy as np
import numpy.ma as ma
A = [1, 2, 3, 4, 5, np.NaN]
B = [2, 3, 4, 5.25, np.NaN, 100]
print(ma.corrcoef(ma.masked_invalid(A), ma.masked_invalid(B)))
Il génère:
[[1.0 0.99838143945703]
[0.99838143945703 1.0]]
En savoir plus ici: https://docs.scipy.org/doc/numpy/reference/maskedarray.generic.html
Dans le cas où vous vous attendez à un nombre différent de nans dans chaque tableau, vous pouvez envisager de prendre un ET logique des masques non nan.
import numpy as np
import numpy.ma as ma
a=ma.masked_invalid(A)
b=ma.masked_invalid(B)
msk = (~a.mask & ~b.mask)
print(ma.corrcoef(a[msk],b[msk]))