Pandas dataframe 将满足两个不同要求的两行相加
Pandas dataframe sum two rows if they meet two different requirements
我有以下table。
| 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 |
我想对前三列相等且 'type' 列中的一行包含 'C' 而另一行包含 'P' 的行求和,然后也其中 'type' = 'C' 金额应为负数,而当 'type' = 'P' 金额应为正数,否则不应相加。如果将它们相加,如果 'amount' 为负数,则 'type' 应为 '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' 未定义。我也不确定这是否是正确的方法,所以如果您有任何提示,请告诉我!
这里有一个解决方案,可能效率不高,但很管用!
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)
我有以下table。
| 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 |
我想对前三列相等且 'type' 列中的一行包含 'C' 而另一行包含 'P' 的行求和,然后也其中 'type' = 'C' 金额应为负数,而当 'type' = 'P' 金额应为正数,否则不应相加。如果将它们相加,如果 'amount' 为负数,则 'type' 应为 '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' 未定义。我也不确定这是否是正确的方法,所以如果您有任何提示,请告诉我!
这里有一个解决方案,可能效率不高,但很管用!
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)