Подсчет количества элементов, отличных от NaN, в матричной матрице ndarray в Python
Мне нужно рассчитать количество элементов, отличных от NaN, в матричной матрице ndarray. Как эффективно это сделать в Python? Вот мой простой код для этого:
import numpy as np
def numberOfNonNans(data):
count = 0
for i in data:
if not np.isnan(i):
count += 1
return count
Есть ли встроенная функция для этого в numpy? Эффективность важна, потому что я делаю анализ больших данных.
Thnx за любую помощь!
Ответы
Ответ 1
np.count_nonzero(~np.isnan(data))
~
инвертирует логическую матрицу, возвращаемую из np.isnan
.
np.count_nonzero
подсчитывает значения, которые не равны 0\false. .sum
должен дать тот же результат. Но, возможно, более четко использовать count_nonzero
Скорость тестирования:
In [23]: data = np.random.random((10000,10000))
In [24]: data[[np.random.random_integers(0,10000, 100)],:][:, [np.random.random_integers(0,99, 100)]] = np.nan
In [25]: %timeit data.size - np.count_nonzero(np.isnan(data))
1 loops, best of 3: 309 ms per loop
In [26]: %timeit np.count_nonzero(~np.isnan(data))
1 loops, best of 3: 345 ms per loop
In [27]: %timeit data.size - np.isnan(data).sum()
1 loops, best of 3: 339 ms per loop
data.size - np.count_nonzero(np.isnan(data))
кажется едва ли самым быстрым здесь. другие данные могут давать разные относительные скорости.
Ответ 2
Альтернативой, но немного более медленной альтернативой является сделать это над индексированием.
np.isnan(data)[np.isnan(data) == False].size
In [30]: %timeit np.isnan(data)[np.isnan(data) == False].size
1 loops, best of 3: 498 ms per loop
Двойное использование оператора np.isnan(data)
и ==
может быть немного избыточным, и поэтому я отправил ответ только для полноты.
Ответ 3
Быстрая запись изменений
Даже если это не самый быстрый выбор, если производительность не является проблемой, которую вы можете использовать:
sum(~np.isnan(data))
.
Производительность:
In [7]: %timeit data.size - np.count_nonzero(np.isnan(data))
10 loops, best of 3: 67.5 ms per loop
In [8]: %timeit sum(~np.isnan(data))
10 loops, best of 3: 154 ms per loop
In [9]: %timeit np.sum(~np.isnan(data))
10 loops, best of 3: 140 ms per loop