Для перф. эффективность, мы можем использовать np.argpartition
-
# a is input ndarray
N = int(np.round(a.size*0.2))
a.flat[np.argpartition(a.flat,kth=N)[:N]] = 0
Пример пошагового прогона -
In [91]: np.random.seed(0)
In [92]: a = np.random.randint(10,100,(4,5))
In [93]: a
Out[93]:
array([[54, 57, 74, 77, 77],
[19, 93, 31, 46, 97],
[80, 98, 98, 22, 68],
[75, 49, 97, 56, 98]])
In [94]: n = 0.2 # ratio of total to be reset
In [95]: N = int(np.round(a.size*n)) # 4
In [96]: a.flat[np.argpartition(a.flat,kth=N)[:N]] = 0
# change 0 to new value to be set, if not zero
In [97]: a
Out[97]:
array([[54, 57, 74, 77, 77],
[ 0, 93, 0, 0, 97],
[80, 98, 98, 0, 68],
[75, 49, 97, 56, 98]])
В качестве альтернативы, мы можем получить пороговое значение а затем сравните и присвойте маску -
In [117]: threshold_val = a.flat[np.argpartition(a.flat,kth=N)[N]]
In [118]: a[a<threshold_val] = 0
In [119]: a
Out[119]:
array([[54, 57, 74, 77, 77],
[ 0, 93, 0, 0, 97],
[80, 98, 98, 0, 68],
[75, 49, 97, 56, 98]])
или используйте np.percentile
-
In [148]: a[a<np.percentile(a,20)] = 0
In [149]: a
Out[149]:
array([[54, 57, 74, 77, 77],
[ 0, 93, 0, 0, 97],
[80, 98, 98, 0, 68],
[75, 49, 97, 56, 98]])