定义堆叠条形图中每个条形的底部

Define the bottom of each bar in a stacked bar graph

我有一个二维数组 absolute_heights,形状为 (2, 6)。我想定义一个形状为 (2, 6) 的新二维数组 bottoms,它在每个位置 i 包含 0 除非

1) absolute_heights[0, i] - absolute_heights[1, i]的符号与absolute_heights[0, i]的符号匹配,此时bottoms[0, i]应设置为absolute_heights[1, i]

2) #1 为假,在这种情况下 bottoms[1, i] 应设置为 absolute_heights[0, i].

下面是实现此目的的 for 循环:

def _get_bottoms(absolute_heights):
    """Define the bottom of each bar in a stacked bar graph.

    Parameters
    ----------
    absolute_heights : np.array
      The absolute height of each bar.  Stacking of the bars is along
      the first axis of this array.

    Returns
    -------
    bottoms : np.array
      The absolute height of the bar in each stack that is closest to
      zero.

    """
    bottoms = np.zeros((2, 6))
    for i, diff in enumerate(absolute_heights[0, :] - absolute_heights[1, :]):
        if np.sign(diff) == np.sign(absolute_heights[0, i]):
            bottoms[0, i] = absolute_heights[1, i]
        else:
            bottoms[1, i] = absolute_heights[0, i]
    return bottoms

numpy 中有更有效的方法吗?

您可以使用布尔索引来避免 for 循环:

def _get_bottoms(absolute_heights):
    bottoms = np.zeros((2,6))
    diff = absolute_heights[0, :] - absolute_heights[1, :]
    i = np.sign(diff) == np.sign(absolute_heights[0, :])
    bottoms[0, i] = absolute_heights[1, i]
    bottoms[1, ~i] = absolute_heights[0, ~i]
    return bottoms

在此函数中,i 是一个布尔数组,指示符号是否匹配(本质上是您的 if 语句)。用 ~i 反转布尔值给出 else 语句的数组。

另一个解决方案使用 np.where

b = np.where(np.sign(ah[0,:]) == np.sign(ah[0,:] - ah[1,:]), ah[1,:], 0.)
b2 = np.where(np.sign(ah[0,:]) != np.sign(ah[0,:] - ah[1,:]), ah[0,:], 0.)
np.vstack((b2,b))

不太可能比上面提到的快得多,可能 - 稍微更具可读性。

np.where 采用 bool 条件数组,然后如果条件为 True 则使用第一个参数(上面的 ah[1,:]),否则使用第二个参数(上面的 ah[0,:])。