首页 > 解决方案 > 如果熊猫数据框满足两个不同的要求,则它们将两行相加

问题描述

我有下表。

| product | check | check1 | type | amount |
|---------|-------|--------|------|--------|
| A       | 1     | a      | c    | -10    |
| A       | 1     | a      | p    | 20     |
| B       | 2     | b      | c    | 20     |
| B       | 2     | b      | p    | 20     |
| C       | 3     | c      | c    | -10    |
| D       | 4     | d      | p    | 15     |
| D       | 4     | d      | c    | -15    |

我想对前三列相等的行的数量求和,并且“类型”列中的一行包含“C”,另一行包含“P”,那么“类型”=“C”的数量应该是负数,当 'type' = 'P' 金额应该是正数,否则它们不应该相加。如果将它们相加,如果“数量”为负,则“类型”应为“c”,否则为“p”。请参阅下面的所需输出:

| product | check | check1 | type | amount |
|---------|-------|--------|------|--------|
| A       | 1     | a      | p    | 10     |
| B       | 2     | b      | c    | 20     |
| B       | 2     | b      | p    | 20     |
| C       | 3     | c      | c    | -10    |
| D       | 4     | d      | p    | 0      |

我已经尝试过group.by前三列,然后应用 lambda 函数;

df = df.groupby(['product', 'check', 'check1']).apply(lambda x, y : x + y, x.loc[(x['type']=='c')], y.loc[(y['type']=='p')], 'amount')

这给出了一个 NameError ,其中未定义“x”。我也不确定这是否是正确的方法,所以如果您有任何提示,请告诉我!

标签: pythonpandassumrows

解决方案


这是一个解决方案,可能效率不高,但它有效!

new_df = pd.DataFrame()
for product in df['product'].unique():
    for check in df[df['product'] == product].check.unique():
        for check1 in df[(df['product'] == product) & (df.check == check)].check1.unique():
            tmp = df[(df['product'] == product) & (df.check == check) & (df.check1 == check1)]
            if len(tmp[((tmp.type == 'c') & (tmp.amount < 0)) | ((tmp.type == 'p') & (tmp.amount > 0))]) != 2:
                new_df = new_df.append(tmp, ignore_index=True)
            else:
                amount = tmp.sum()['amount']
                type = 'c' if amount < 0 else 'p'                
                elt = {
                    'product': product,
                    'check': check,
                    'check1': check1,
                    'type': type,
                    'amount': amount
                }
                new_df = new_df.append(pd.Series(elt), ignore_index=True)

推荐阅读