python-3.x - Pandas,按行计算,第一个值满足条件
问题描述
我有一个数据框:
df = pd.DataFrame(
[
[10,20,40],
[2,1,26],
[1, 2, 60],
], columns = ['f1', 'f2', 'f3']
)
df['cumsum'] = df.sum(axis=1)
df['cumsum_perc'] = (df['cumsum'] * 0.1).astype(int)
| | f1 | f2 | f3 | cumsum | cumsum_perc |
|---:|-----:|-----:|-----:|---------:|--------------:|
| 0 | 10 | 20 | 40 | 70 | 7 |
| 1 | 2 | 1 | 26 | 29 | 2 |
| 2 | 1 | 2 | 60 | 63 | 6 |
正如你所看到的,对于每一行,我计算了累积总和,而不是累积总和的任意(在本例中为 10%)百分比的累积总和。
每个 f 列都有其思考值(f_pon),f1 = 1,f2 = 2,f3 = 3。
现在,对于每一行,我必须找出具有最高值的 f 列,其值小于或等于 cumsum_perc (f_le) 以确定它的 f_pon。
让我们以第三行为例。
f_le = f2 (2 < 6),这意味着 f_pon = 2。
现在我必须看看 cumsum_perc - f_le 列中是否有任何提醒。rem = cumsum_perc (6) - f_le (2) = 4。
考虑到 f_le (f3) 右侧第一个 f 列的值,我必须计算提醒的百分比,所以这里我们有 rem_perc = rem (4) / f3 (60) = 0.066。
第三行的最终结果是 f_pon (2) + rem_perc = 2.066。
如果我们对第一行应用相同的逻辑,那么 f1 就是 f_le,并且没有提醒,因为 cumsum_perc (7) - f_le (10) = -3。如果 rem 是负数,它应该设置为 0。所以结果是 f1_pon (1) + rem (0) / f2 (20) = 1
对于第二行,结果也是 1,因为没有提醒。
如何以最有效的方式计算每一行的最终结果?
解决方案
老实说,很难遵循你的规则,但既然你现在是你的规则,我建议实现一个辅助函数并df.apply(helper, axis=1)
明智地使用行。
这可能不是最快的实现,但至少你得到了结果。
def helper(x):
basic_set = x[['f1','f2','f3']]
cumsum_perc = x['cumsum_perc']
f_pon = basic_set[basic_set<cumsum_perc].max()
rem = cumsum_perc - f_pon
if not rem:
rem = 0
rem_perc = rem / x['cumsum']
if not rem_perc:
rem_perc = 0
return f_pon + rem_perc
df['ans'] = df.apply(helper, axis=1)
>>> df
f1 f2 f3 cumsum cumsum_perc ans
0 10 20 40 70 7 NaN
1 2 1 26 29 2 1.034483
2 1 2 60 63 6 2.063492
helper
如果我的错误,我认为您可以调整。
推荐阅读
- python-3.x - 如何用逗号,反斜杠分割字符串,并将逗号和反斜杠保持在python中的位置
- python - 如何创建多个线程
- python - Keras 生成器一直在洗牌,尽管它被要求不要
- mysql - 如何在客户的第一个订单上找到 sku?
- python - 使用 Py2app 识别包中的嵌套文件
- javascript - 使用空格在 html textarea 中的单词之间保持相同的间隙
- javascript - 获取javascript类中静态方法的值
- javascript - 如何导入 sanitize.js 以响应应用程序功能/类未找到
- scala - 如何使用一些正则表达式在 scala 中删除多个列?
- vue.js - quasar 无法建立资产文件夹