如何根据一行的平均值设置阈值?

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


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

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


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

实际上使用的是列平均值,这对某些人也可能有用。它相当于:


new_arr = arr.copy()

for i, row in enumerate(arr.T):

    avg = np.mean(row)

    for j, pixel in enumerate(row):

        if pixel > avg:

            new_arr[j,i] = 0

        else:

            new_arr[j,i] = 1


湖上湖
浏览 219回答 3
3回答

慕容3067478

设置a = np.arange(25).reshape((5,5))你可以用keepdims与mean:a[a > a.mean(1, keepdims=True)] = 0array([[ 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.]])文档中说明了这样做的好处:如果将其设置为 True,则减少的轴将作为尺寸为 1 的维度保留在结果中。使用此选项,结果将针对输入数组正确广播。

慕娘9325324

您可以使用np.mean(a, axis=1)来获取每行的平均值,将其广播到 的形状a,并将所有值设置a > broadcasted_mean_array为 0:示例:a = np.arange(25).reshape((5,5))>>> aarray([[ 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 >>> aarray([[ 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]])

忽然笑

使用axis关键字表示您的意思:avg = np.mean(arr, axis=0)然后使用它来创建您的掩码并分配您想要的值:mask = avg>=arrnew_arr = np.zeros(arr.shape)arr[mask] = 1当然,您可以直接从掩码创建一个新数组,而无需两步方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python