python - 对多行应用蒙版(语法糖?)

标签 python numpy

我正在寻找一种优雅(或更优雅)的方式来在 numpy 中编写特定用例的代码。该用例是一个大型数据集(因此效率很重要),包含 100 多个字段、超过 1,000 行代码以及多个代码段,其中我只想处理其中的一部分字段。只要我处理所有观察结果,这在普通 numpy 中就是干净且高效的:

wages = np.arange(40000,60000,2000)
cg    = np.arange(0,100000,10000)
ded   = np.repeat([6000,9000],5) 
exem  = np.repeat([2000,4000],5) 

agi  = wages + cg
tinc = agi - ded
tinc = tinc - exem

但是在许多代码小节中,我只想处理观察结果的子集,例如 30 行代码,这是我能想到的最好的方法:

agi  = wages + cg
mask = wages < 50001
tinc = agi

tinc[mask] = agi[mask] - ded[mask]
tinc[mask] = tinc[mask] - exem[mask]

这并不可怕,不要误会我的意思,但是将其乘以数百个变量和数百行代码。有没有办法在不诉诸 cython/numba 循环的情况下执行类似以下操作?

# fake code, just to convey the desired syntax
agi  = wages + cg
tinc = agi

mask( wages < 50001 ):    # i.e. inside a python loop, would be "if wages < 50001:"
   tinc = agi - ded
   tinc = tinc - exem

换句话说,我想定义代码的子部分,并指定完全相同的掩码应应用于代码部分中的每个数组,而无需为每个单个数组显式键入掩码。

(顺便说一句,我知道通过 pandas 可能有一些替代方法,但现在更愿意通过 numpy 探索我的最佳选择。稍后我可能会用 pandas 标签重新问这个问题。)

最佳答案

我不推荐这样做,但是......你可以使用一个非常神奇的上下文管理器来做到这一点。例如:

@contextlib.contextmanager
def masking(namespace, mask):
    # If you don't have a fixed set of maskable variables, make it
    # an instance/global/local variables, like `_names`, or just
    # [name for name, value in namespace.items() if isiinstance(value, np.ndarray)]
    names = 'tinc agi dec exem'.split()
    stash = {name: namespace[name] for name in names}
    for name in names:
        namespace[name] = namespace[name][mask]
    try:
        yield
    finally:
        for name in names:
            namespace[name] = stash[name]

现在你可以这样做:

with masking(globals(), wages < 50001):
    tinc = agi - dec
    tinc = tinc - exem

with masking(self.__dict__, self.wages < 50001):
    self.tinc = self.agi - self.dec
    self.tinc = self.tinc - self.exem

# etc.

关于python - 对多行应用蒙版(语法糖?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25856250/

相关文章:

python - 如何对 scipy.sparse.csr_matrix 类型的矩阵进行元素运算?

python - 如何用特定集合中的元素填充 python 中的列表?

python - python中使用特定顺序对元素进行排序

python - 使用 BeauitifulSoup 进行网页抓取错误 : [Errno 10061]

python - 将矩阵的每个元素作为一个 block 重复到新矩阵中

python - 从对象列表创建 pandas Dataframe

python - 如何保存 Python 交互式 session ?

python - Python 导入中的命名空间

python - 优化 numpy 网格创建以实现高效插值

python - numpy 用轴上连续元素的总和有效地替换 2d bool 数组