Не пойму, почему numpy отдаёт nan. Если есть два разных массива, то вылетают nan
np.corrcoef([0.1, 0.1, 0.1], [0.9, 0.9, 0.9])
array([[ 1., nan],
[ nan, nan]])
При этом, если два одинаковых массива, то этого не происходит:
np.corrcoef([0.1, 0.1, 0.1], [0.1, 0.1, 0.1])
array([[ 1., 1.],
[ 1., 1.]])
Также непонятно, почему corrcoef отдаёт все nan для нулей:
np.corrcoef([0, 0, 0], [0.1, 0.1, 0.1])
array([[ nan, nan],
[ nan, nan]])
Ответ
Если смоделировать то что происходит внутри функции np.corrcoef()
In [37]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9]
# расчет ковариционной матрицы
In [38]: c = np.cov(x,y)
# для указанных значений - она имеет нулевые значения для 3-х из 4-х элементов
# в результате `np.corrcoef()` на месте этих элементов будут стоять NaN
In [39]: c
Out[39]:
array([[ 2.88889492e-34, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00]])
In [40]: d = np.diag(c)
In [41]: d
Out[41]: array([ 2.88889492e-34, 0.00000000e+00])
In [42]: stddev = np.sqrt(d.real)
In [43]: stddev
Out[43]: array([ 1.69967494e-17, 0.00000000e+00])
В следующей строке мы получим NaN как результат деления на ноль:
In [44]: c /= stddev[:, None]
...\py36\Scripts\ipython3:1: RuntimeWarning: invalid value encountered in true_divide
In [45]: stddev[:, None]
Out[45]:
array([[ 1.69967494e-17],
[ 0.00000000e+00]])
In [46]: c
Out[46]:
array([[ 1.69967494e-17, 0.00000000e+00],
[ nan, nan]])
Как это обойти - прибавить очень маленькое число к одному или нескольким элементам второго массива:
In [109]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9+1e-16]
In [110]: np.corrcoef(x,y)
Out[110]:
array([[ 1. , -0.57735027],
[-0.57735027, 1. ]])
или
In [111]: x=np.array([0.1, 0.1, 0.1]); y=np.array([0.9,0.9,0.9])+1e-16
In [112]: np.corrcoef(x,y)
Out[112]:
array([[ 1., -1.],
[-1., 1.]])
Комментариев нет:
Отправить комментарий