首页 > 解决方案 > 对 pandas 列求和,不包括基于其他列值的某些行

问题描述

我正在尝试从测试群体中确定小部件故障的数量。

每个小部件都可能以 0、1 或多种方式失败。我想计算每种失败方法的失败次数,但是一旦已知小部件失败,就应该将其从未来的总和中排除。换句话说,故障模式是已知的和有序的。如果小部件通过模式 1 和模式 3 失败,我不关心模式 3:我只想计算模式 1。

我有一个数据框,每个项目一行,每个故障模式一列。如果小部件在该模式下失败,则列值为 1,否则为 0。

d = {"item_1": 
         {"failure_1":0, "failure_2":0}, 
     "item_2":
         {"failure_1":1, "failure_2":0}, 
     "item_3":
         {"failure_1":0, "failure_2":1}, 
     "item_4":
         {"failure_1":1, "failure_2":1}}

df = pd.DataFrame(d).T
display(df)

输出:

        failure_1  failure_2
item_1          0          0
item_2          1          0
item_3          0          1
item_4          1          1

如果我只想对列求和,那很简单:df.sum(). 如果我想计算失败百分比,也很容易:df.sum()/len(df). 但这会计算以多种方式多次失败的小部件。对于所述问题,我能想到的最好的方法是:

# create empty df to store results
df2 = pd.DataFrame(columns=["total_failures"])

for col in df.columns:
    # create a row, named after the column, and assign it the value of the sum
    df2.loc[col] = df[col].sum()

    # drop rows in the df column that are equal to 1
    df = df.loc[df[col] != 1]

display(df2)

输出:

          total_failures
failure_1              2
failure_2              1

这需要创建另一个数据框(这很好),但还需要遍历现有的数据框列一次删除几行。如果数据框需要一段时间才能生成,或者需要用于未来的计算,则这是不可行的。我可以处理对列的迭代。

有没有办法在不删除原始 df 或制作临时副本的情况下做到这一点?(不适用于大型数据集。)

标签: pandas

解决方案


您可以在值大于 1 的任何地方执行 a cumsumon ,然后将其作为sum :axis=1mask0

out = df.mask(df.cumsum(axis=1).gt(1), 0).sum().to_frame('total_failures')

print(out)

           total_failures
failure_1               2
failure_2               1

这样原件df也得以保留。


推荐阅读