使用 pandas df 的具有多个 if 的 lambda 函数
Posted
技术标签:
【中文标题】使用 pandas df 的具有多个 if 的 lambda 函数【英文标题】:lambda function with multiple ifs using pandas df 【发布时间】:2017-05-10 14:24:23 【问题描述】:我有一个包含收入和成本数据的简单 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
这只允许一个 else 条件。
【问题讨论】:
这与您关于创建lambda
函数的问题无关,但&
是Python 中的位与运算符。当您执行逻辑与(这似乎是您想要的)时,您需要 and
运算符。这两个运算符对于布尔值 True
和 False
的工作方式相同,但如果您在操作中涉及其他“真实”值(例如比较 1 & 2
和 1 and 2
)。
【参考方案1】:
熊猫矢量化
r = x.rev.div(x.cost)
r.abs().add(r < 0).rename('revenue_cost_ratio')
numpy 矢量化 顺便说一句,我会用这个
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,我们很好。因此是一开始的功能。
【讨论】:
很好的解释。我怎么给你赏金呢? :P 直到 2 天才能发放赏金。没必要,但我很欣赏这个姿态(当然,如果你坚持,我不能阻止你:-)【参考方案2】:不要使用应用。它非常慢。使用嵌套的 where。
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']))
【讨论】:
以上是关于使用 pandas df 的具有多个 if 的 lambda 函数的主要内容,如果未能解决你的问题,请参考以下文章
如何使用具有多个源列的 pandas_udf 将多个列添加到 pyspark DF?
将多个键上的 pandas 数据帧映射为列或 multiIndex