我有一个简单的df,包含收入和成本数据。在我的情况下,成本可能是负面的。
我想按如下方式计算收入与成本比率:
if ((x['cost'] < 0) & (x['rev'] >=0 )):
x['r_c_ratio'] = (x['rev'] + abs(x['cost'])) / abs(x['cost'])
elif((x['cost'] > 0) & (x['rev'] <=0 )):
x['r_c_ratio'] = (x['cost'] + abs(x['rev'])) / x['cost']
else:
x['r_c_ratio'] = x['rev'] / x['cost']
如何在lambda函数中实现它?
df['revenue_cost_ratio'] = df.apply(lambda x:....
根据这个link,lambda语法是:
lambda x: True if x % 2 == 0 else False
这只允许其他条件。
答案 0 :(得分:2)
pandas vectorized
r = x.rev.div(x.cost)
r.abs().add(r < 0).rename('revenue_cost_ratio')
numpy vectorized
顺便说一句,我使用这个
r = x.rev.values / x.cost.values
pd.Series(np.abs(r) + (r < 0), x.index, name='revenue_cost_ratio')
如果您坚持使用lambda
f = lambda x: (x.rev * x.cost < 0) + abs(x.rev / x.cost)
x['revenue_cost_ratio'] = x.apply(f)
让我们来看看你的3个案例
案例1
if ((x['cost'] < 0) & (x['rev'] >=0 )):
x['r_c_ratio'] = (x['rev'] + abs(x['cost'])) / abs(x['cost'])
x['cost'] < 0
时,abs(x['cost'])
仅为-1 * x['cost']
,因此可以简化为
(x['rev'] - x['cost']) / -x['cost']
或
(x['cost'] - x['rev']) / x['cost']
案例2
elif((x['cost'] > 0) & (x['rev'] <=0 )):
x['r_c_ratio'] = (x['cost'] + abs(x['rev'])) / x['cost']
x['rev'] <= 0
时,abs(x['rev'])
仅为-1 * x['rev']
,因此可以简化为
(x['cost'] - x['rev']) / x['cost']
哇这和案例一样!但我们可以进一步减少这种情况
1 - x['rev'] / x['cost']
我们什么时候使用它?似乎只有x['rev']
或x['cost']
为负数而非两者都有。那么,只有当这个比例是负数时才会发生。
案例3
x['rev'] / x['cost']
再次!真好运气!这看起来很像1 - x['rev'] / x['cost']
因此,如果我们预先计算x['rev'] / x['cost']
,测试它是否消极并将其返回或减去1,我们就是好的。因此,开头的功能。
答案 1 :(得分:1)
不要使用申请。这非常慢。使用嵌套的地方。
np.where((x['cost'] < 0) & (x['rev'] >=0 ), (x['rev'] + abs(x['cost'])) / abs(x['cost']),
np.where((x['cost'] > 0) & (x['rev'] <=0 ), (x['cost'] + abs(x['rev'])) / x['cost'],
x['rev'] / x['cost']))