【问题标题】:How can I vectorize a masked weighted average with condition using numpy?如何使用 numpy 对带有条件的掩码加权平均值进行矢量化?
【发布时间】:2021-01-25 00:52:20
【问题描述】:

未矢量化的代码如下:

import numpy as np
import numpy.ma as ma

np.random.seed(42)
H = np.random.uniform(0.1, 1.0, size=(6,8))
r, c = H.shape

mask = H.max(axis=1) > 0.95


x = np.linspace(0, 10, c)
weighted_averages = ma.masked_all((r,), dtype=H.dtype)

for i in range(r):
    if mask[i]:
        weighted_averages[i] = np.average(x, weights=H[i, :])

这是我对它进行矢量化的尝试:


_, xx = np.mgrid[0:10:r*1j, 0:10:c*1j]
not_mask = np.logical_not(mask)


weighted_averages = np.average(xx, weights=H, axis=1)
mwa = ma.masked_array(weighted_averages, mask=not_mask)

在输出相同的意义上,它有效,但我在“作弊”,因为我首先计算所有平均值,然后屏蔽“不需要的”值。我怎样才能避免不必要的计算?我猜我必须以某种方式屏蔽xxH,或两者兼而有之。

【问题讨论】:

  • 试图避免不必要的计算可能比仅仅做这些计算更昂贵。

标签: python numpy weighted-average masked-array


【解决方案1】:

这个怎么样-

import numpy as np
import numpy.ma as ma

np.random.seed(42)
H = np.random.uniform(0.1, 1.0, size=(6,8))
r, c = H.shape

mask = H.max(axis=1) > 0.95

x = np.linspace(0, 10, c)

H_mask = H[mask]
wa = (np.sum(x * H_mask, axis=1))/np.sum(H_mask, axis=1)
weighted_averages = ma.masked_all((r,), dtype=H.dtype)

weighted_averages[mask] = wa

只需先屏蔽数组,然后取平均值。我不认为你可以在这里使用np.average,因为它似乎不支持广播。因此,只需手动进行平均。

【讨论】:

  • 我怎么能直接屏蔽H而不是H_mask = H[mask]?我的意思是创建一个屏蔽数组,其中满足H.max(axis=1) <= 0.95 的行被屏蔽?我试过np.ma.masked_less_equal(H, 0.95),但这并不等效,因为我想屏蔽沿该行的最大值<= 0.95的行。
  • 我不确定你为什么需要它。这解决了你原来的问题,对吗?它可以创建您需要的数组,而不会浪费任何额外的时间来计算您不需要的东西。
  • 但是如果你出于某种原因想要这样做,你可以这样做 H_mask = ma.masked_all((r,c), dtype=H.dtype)H_mask[mask] = H[mask]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 2021-05-07
相关资源
最近更新 更多