Вероятно, есть лучший способ, но рассмотрим:
import numpy as np
x = np.array([[1,2,3,4],
[1,2,3,4],
[np.NaN, np.NaN, np.NaN, np.NaN],
[1,2,3,4]])
# Get a vector of 1-d indexed indexes of non NaN elements
indices = np.where(np.isfinite(x).ravel())[0]
# Shuffle the indices, select the first 30% (rounded down with int())
to_replace = np.random.permutation(indices)[:int(indices.size * 0.3)]
# Replace those indices with the mean (ignoring NaNs)
x[np.unravel_index(to_replace, x.shape)] = np.nanmean(x)
print(x)
Пример выходных данных
[[ 2.5 2. 2.5 4. ]
[ 1. 2. 3. 4. ]
[ nan nan nan nan]
[ 2.5 2. 3. 4. ]]
NaN никогда не изменится и пол (0,3 * число не-NaN элементов) будет установлено на среднее значение (среднее значение, игнорирующее NaNs).