Среднее число ненулевых значений

У меня есть матрица размера N * M, и я хочу найти среднее значение для каждой строки. Значения находятся в диапазоне от 1 до 5, а записи, которые не имеют никакого значения, устанавливаются в 0. Однако, когда я хочу найти среднее значение, используя следующий метод, это дает мне неверное среднее значение, так как оно также подсчитывает записи, которые имеют значение 0.

matrix_row_mean= matrix.mean(axis=1)

Как я могу получить среднее значение только ненулевых значений?

Ответы на вопрос(2)

которое используетзамаскированный массив, Чтобы проиллюстрировать детали, давайте создадим нижнюю треугольную матрицу только с одним:

matrix = np.tril(np.ones((5, 5)), 0)

Если вам не понятна терминология, приведенная выше, эта матрица выглядит следующим образом:

  [[ 1.,  0.,  0.,  0.,  0.],
   [ 1.,  1.,  0.,  0.,  0.],
   [ 1.,  1.,  1.,  0.,  0.],
   [ 1.,  1.,  1.,  1.,  0.],
   [ 1.,  1.,  1.,  1.,  1.]]

Теперь мы хотим, чтобы наша функция возвращала в среднем 1 для каждой строки. Или другими словами, что среднее значение по оси 1 равно вектору из пяти. Для этого мы создали матрицу в маскегде записи, значения которых равны нулю, считаются недействительными, Это может быть достигнуто сnp.ma.masked_equal:

masked = np.ma.masked_equal(matrix, 0)

Наконец, мы выполняем в этом массиве пустые операции, которые будут систематически игнорировать маскированные элементы (0). Имея это в виду, мы получаем желаемый результат путем:

masked.mean(axis=1)

Это должно привести к вектору, записи которого являются только единицами.

Более подробно выводnp.ma.masked_equal(matrix, 0) должен выглядеть так:

masked_array(data =
 [[1.0 -- -- -- --]
 [1.0 1.0 -- -- --]
 [1.0 1.0 1.0 -- --]
 [1.0 1.0 1.0 1.0 --]
 [1.0 1.0 1.0 1.0 1.0]],
             mask =
 [[False  True  True  True  True]
 [False False  True  True  True]
 [False False False  True  True]
 [False False False False  True]
 [False False False False False]],
       fill_value = 0.0)

Это указывает на то, что значения на-- считаются недействительными. Это также показано в атрибуте маски замаскированных массивов как Trueчто указывает на то, что это недопустимый элемент и поэтому следует игнорировать.

Наконец, вывод средней операции над этим массивом должен выглядеть следующим образом:

masked_array(data = [1.0 1.0 1.0 1.0 1.0],
             mask = [False False False False False],
       fill_value = 1e+20)
 David Alvarez07 мая 2019 г., 16:40
действительно четкое объяснение с отличными простыми примерами. .. Спасибо !
Решение Вопроса

днения суммирования по каждой строке. Таким образом, реализация будет выглядеть примерно так:

np.true_divide(matrix.sum(1),(matrix!=0).sum(1))

Если вы используете более старую версию NumPy, вы можете использовать преобразование числа с плавающей запятой для заменыnp.true_divide, вот так -

matrix.sum(1)/(matrix!=0).sum(1).astype(float)

Пробный прогон -

In [160]: matrix
Out[160]: 
array([[0, 0, 1, 0, 2],
       [1, 0, 0, 2, 0],
       [0, 1, 1, 0, 0],
       [0, 2, 2, 2, 2]])

In [161]: np.true_divide(matrix.sum(1),(matrix!=0).sum(1))
Out[161]: array([ 1.5,  1.5,  1. ,  2. ])

Другим способом решения этой проблемы было бы заменить нули наNaNs а затем использоватьnp.nanmeanкоторый бы игнорировал теNaNs и в действительности эти оригинальныеzeros, вот так -

np.nanmean(np.where(matrix!=0,matrix,np.nan),1)

С точки зрения производительности, я бы рекомендовал первый подход.

 HimanAB23 июл. 2016 г., 16:01
нп не имеет атрибута true_divide
 Divakar23 июл. 2016 г., 16:06
@HimanUCC Пожалуйста, ознакомьтесь с изменениями.
 hpaulj23 июл. 2016 г., 19:22
Подход с маскированным массивом компактен (но не обязательно быстрее):np.ma.masked_equal(matrix, 0).mean(axis=1)

Ваш ответ на вопрос