如何基于行的平均值进行阈值设置?

时间:2018-11-01 17:52:20

标签: python numpy

我有一个二维数组。我想将每行中大于该行平均值的所有值设置为0。 一些天真的这样做的代码是:

db.run('CREATE TABLE table1 ( number integer, colour json)');

这非常慢,我想知道是否有某种方法可以使用Numpy索引? 如果它是整个矩阵的平均值,我可以简单地做:

new_arr = arr.copy()
for i, row in enumerate(arr):
    avg = np.mean(row)
    for j, pixel in enumerate(row):
        if pixel > avg:
            new_arr[i,j] = 0
        else:
            new_arr[i,j] = 1

是否可以使用一维平均值数组或类似的方法对每行平均值执行此操作?

编辑: 建议的解决方案:

mask = arr > np.mean(arr)
arr[mask] = 0
arr[np.logical_not(mask)] = 1

实际上是使用列平均,这对某些人也可能有用。它等效于:

avg = np.mean(arr, axis=0)
mask = arr > avg
new_arr = np.zeros(arr.shape)
arr[mask] = 1

3 个答案:

答案 0 :(得分:2)

您可以使用np.mean(a, axis=1)来获取每一行的均值,将其广播为a的形状,并将a > broadcasted_mean_array的所有值设置为0:

示例

a = np.arange(25).reshape((5,5))
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

a[a > np.broadcast_to(np.mean(a,axis=1),a.shape).T] = 0 

>>> a
array([[ 0,  1,  2,  0,  0],
       [ 5,  6,  7,  0,  0],
       [10, 11, 12,  0,  0],
       [15, 16, 17,  0,  0],
       [20, 21, 22,  0,  0]])

答案 1 :(得分:2)

设置

a = np.arange(25).reshape((5,5))

您可以将keepdimsmean一起使用:

a[a > a.mean(1, keepdims=True)] = 0

array([[ 0,  1,  2,  0,  0],
       [ 5,  6,  7,  0,  0],
       [10, 11, 12,  0,  0],
       [15, 16, 17,  0,  0],
       [20, 21, 22,  0,  0]])

使用keepdims=True,得出mean的以下结果:

array([[ 2.],
       [ 7.],
       [12.],
       [17.],
       [22.]])

in the docs指出了这样做的好处:

  

如果将其设置为True,则缩小的轴将保留为尺寸为1的尺寸。使用此选项,结果将针对输入数组正确广播。

答案 2 :(得分:1)

使用axis关键字表示您的意思:

avg = np.mean(arr, axis=0)

然后使用它来创建掩码并分配所需的值:

mask = avg>=arr
new_arr = np.zeros(arr.shape)
arr[mask] = 1

当然,您可以从蒙版直接创建一个新数组,而无需采取两步法。