У меня есть два массива данных, которые я хочу пересечь, и получить длину задержки (если есть) между двумя массивами, а затем нормализовать ее между 0 и 1. Например:
import numpy as np
x = [0,1,1,1,2,0,0]
y = [0,0,0,1,1,1,2]
corr = np.correlate(a,b, 'full')
norm = np.linalg.norm
normalized = corr/(norm(a)*norm(b))
возвращает:
[0.0, 0.0, 0.29, 0.43, 0.57, 1.0, 0.57, 0.43, 0.29, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
Проблема заключается в следующем: мне нужно сопоставить две графики, и массив X не является регулярным (и не то же самое для двух массивов, есть только некоторое значение y, связанное с некоторым значением x), поэтому я интерполирую данные до корреляции с scipy.interpolate.interp1d
и это приводит к элементам NaN в моем массиве. В этот момент корреляционная функция возвращает NaN
Например:
import numpy as np
x = [0,1,1,1,2,0,np.nan]
y = [np.nan,0,0,1,1,1,2]
corr = np.correlate(a,b, 'full')
norm = np.linalg.norm
normalized = corr/(norm(a)*norm(b))
возвращает:
[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
Я, наконец, понял, что получаю это, потому что норма (а) дает NaN, мой вопрос: как я могу просто игнорировать эти значения NaN, есть ли лучший способ перекрестно сопоставить два массива? Я уже тестировал для запуска interp1d
с fill_value='extrapolate'
но это вызывает проблемы в вычислении корреляции. Есть ли другое значение, которое я могу передать fill_value, которое "игнорирует" недостающие значения в данных?
Кроме того, np.correlate(x,y)
возвращает NaN
но если мы посмотрим на np.correlate(x,y,'full')
он действительно вернется [ 0. 0. 2. 3. 4. 7. 4. nan nan nan nan nan nan nan nan]
, Почему numpy принимает NaN как максимальное значение?
Прежде всего, замените значения NAN, возможно, средним или режимом покоя элементов. Это самая наивная техника. Как работать с NAN может быть совершенно другим вопросом. Вы можете использовать np.nanmean()
для этой цели.
Ненужный коррелят - это не то, что вы ищете.
Из документации:
Кросс-корреляция двух одномерных последовательностей.
Эта функция вычисляет корреляцию, как это обычно определено в текстах обработки сигналов:
c_ {av} [k] = sum_n a [n + k] * conj (v [n])
Вы должны взглянуть на коэффициент корреляции Пирсона, который является мерой линейной корреляции между двумя переменными X и Y.
from scipy.stats.stats import pearsonr
x = [0,1,1,1,2,0,np.nan]
y = [np.nan,0,0,1,1,1,2]
corr = pearsonr(x,y, 'full')
или вы также можете использовать
numpy.corrcoef(x,y)
который возвращает 2d-массив, объясняющий корреляцию между двумя (или более) массивами.
np.corrcoef
, я использовал np.correlate для примера из-за его простоты. Но не знал Pearsonr, спасибо
import numpy as np; x = np.array([0,1,1,1,2,0,np.nan]); y = np.array([np.nan,0,0,1,1,1,2]); normx=norm(x[~np.isnan(x)]); normy=norm(y[~np.isnan(y)]); corr=np.correlate(np.ma.array(x,mask=np.isnan(x)),np.ma.array(y,mask=np.isnan(y)),'full'); print corr/(normx*normy)
В основном я бы использовал маскированные массивы, где nan игнорируется для ввода в функциюnp.correlate
.