Numpy:裁剪数组值并将剩余值带到下一个的智能方法

w80xi6nr  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(94)

由于底层的数据结构,我的数组中的值有一个最大值。
在numpy中有没有一种聪明的方法来裁剪数组并将剩余的元素带到下一个元素?
(我在这里将其简化为1D数组)

In [1]: import numpy as np

In [2]: array = np.arange(10, 1, -1)

In [3]: rest = 0

In [4]: array
Out[4]: array([10,  9,  8,  7,  6,  5,  4,  3,  2])

In [5]: for i, x in enumerate(array):
   ...:     tmp = array[i] + rest
   ...:     if tmp > 8:
   ...:         array[i] = 8
   ...:         rest = tmp - 8
   ...:     elif tmp <= 8:
   ...:         array[i] = tmp
   ...:         rest = 0
   ...:

In [6]: array
Out[6]: array([8, 8, 8, 8, 8, 5, 4, 3, 2])

这是可行的,但在numpy中是否有更聪明的方法来实现这一点,也支持更多的维度?例如,一个向量数组。当它们结合在一起时,道路将不会相同,但它们将总结为相同。

nle07wnf

nle07wnf1#

计算每个单元格中剩余的空间,即我们可以添加什么来获得最大单元格值。计算总超额,即超过需要重新分配的最大单元值的值的总和。
然后创建一个布尔数组,指示哪些单元格需要更改。导出需要更改的最后一个单元格的索引。
用最大单元格值填充需要更改的单元格。现在我们只需要修正最后一个改变的单元格,因为这里可能需要更小的值来达到正确的总和。
我们总是从左到右填充数组。如果因为总和太大而无法完成,则返回所有单元格填充到最大值的数组。

import numpy as np

def redistribute(a, cell_max):
    full = np.full_like(a, cell_max)
    if a.sum() >= full.sum():
        return full
    
    space_left = np.maximum((full - a), 0)
    excess = np.where(a > cell_max, a - cell_max, 0).sum()  
    
    needs_change = space_left.cumsum() < excess
    last_change = np.argmin(needs_change)
    
    result = np.where(needs_change, full, np.minimum(a, cell_max))
    result[last_change] += a.sum() - result.sum()
    return result
    
    
redistribute(np.arange(10, 1, -1), 8)
# -> array([8, 8, 8, 8, 8, 5, 4, 3, 2])

对于更高的维度,你可以解开数组,应用这个函数并重塑。

相关问题