Исходя из моих грубых расчетов, вам нужна корреляционная матрица, содержащая 100 000 ^ 2 элементов.Это занимает около 40 ГБ памяти, при условии плавающих значений.
Это, вероятно, не поместится в памяти компьютера, в противном случае вы можете просто использовать corrcoef
.Есть причудливый подход, основанный на собственных векторах, который я не могу найти прямо сейчас, и который попадает в (обязательно) сложную категорию ... Вместо этого полагайтесь на тот факт, что для данных с нулевым средним значение ковариация может быть найдена с использованием точечного произведения.
z0 = z - mean(z, 1)[:, None]
cov = dot(z0, z0.T)
cov /= z.shape[-1]
И это можно превратить в корреляцию путем нормализации по отклонениям
sigma = std(z, 1)
corr = cov
corr /= sigma
corr /= sigma[:, None]
Конечно, использование памяти все еще остается проблемой.Вы можете обойти это с массивами, отображаемыми в память (убедитесь, что он открыт для чтения и записи) и параметром out
, равным dot
(другой пример см. Оптимизация кода больших данных с небольшим объемом оперативной памяти )
N = z.shape[0]
arr = np.memmap('corr_memmap.dat', dtype='float32', mode='w+', shape=(N,N))
dot(z0, z0.T, out=arr)
arr /= sigma
arr /= sigma[:, None]
Затем вы можете перебрать полученный массив и найти индексы с большим коэффициентом корреляции.(Вы можете найти их непосредственно с помощью where(arr > 0.95)
, но сравнение создаст очень большой логический массив, который может или не может поместиться в памяти).