Python 根据递减值计算新值
问题:Python 根据递减值计算新值,python,pandas,Python,Pandas,问题: import pandas as pd ALLOWANCE = 100 values = pd.Series([85, 10, 25, 30]) desired = pd.Series([0, 0, 20, 30]) 我想做的是,通过不断减少的基数,逐步减少系列中的值 我不确定这方面的术语-我确实认为我可以用cumsum和diff做些什么,但我认为我在这方面做了一场白费力气的追逐 起始代码: import pandas as pd ALLOWANCE = 100 values =
import pandas as pd
ALLOWANCE = 100
values = pd.Series([85, 10, 25, 30])
desired = pd.Series([0, 0, 20, 30])
我想做的是,通过不断减少的基数,逐步减少系列中的值
我不确定这方面的术语-我确实认为我可以用cumsum
和diff
做些什么,但我认为我在这方面做了一场白费力气的追逐
起始代码:
import pandas as pd
ALLOWANCE = 100
values = pd.Series([85, 10, 25, 30])
desired = pd.Series([0, 0, 20, 30])
所需输出:
import pandas as pd
ALLOWANCE = 100
values = pd.Series([85, 10, 25, 30])
desired = pd.Series([0, 0, 20, 30])
理由:
import pandas as pd
ALLOWANCE = 100
values = pd.Series([85, 10, 25, 30])
desired = pd.Series([0, 0, 20, 30])
以余量为基数开始
-系列
中的每个值都会减少剩余的金额,就像余量本身一样,因此会发生以下步骤:
- 从100开始,我们可以完全删除
85
,因此它变为0
,现在剩下15
作为余量
- 下一个值是
10
,我们仍然有15
可用,因此它再次变为0
,剩下的是5
- 下一个值是
25
-我们只剩下5
,因此这变成了20
,现在我们没有更多的余量
- 下一个值是
30
,由于没有余量,该值保持为30
它应该与一起工作,而循环:
ii = 0
while (ALLOWANCE > 0 and ii < len(values)):
if (ALLOWANCE > values[ii]):
ALLOWANCE -= values[ii]
values[ii] = 0
else:
values[ii] -= ALLOWANCE
ALLOWANCE = 0
ii += 1
ii=0
而(容差>0且ii值[ii]):
容差-=数值[ii]
值[ii]=0
其他:
值[ii]=余量
容差=0
ii+=1
这可能不是很好,但目前这是一种通过以下方式实现的方法:
或者更简单地说:
In [58]:
values.apply(reduce)
Out[58]:
0 0
1 0
2 20
3 30
dtype: int64
您使用cumsum
和diff
的想法行之有效。它看起来不太复杂;不确定是否有更短的解决方案。首先,我们计算累积和,对其进行运算,然后返回(diff
有点像是cumsum
的反函数)
导入数学
c=值。总和()-容差
#现在我们有[-15,-5,20,50]
c[c<0]=0#负值在这里没有意义
#(c-c.shift(1))#按照你最初的cumsum
和diff
想法,你可以写:
>>> (values.cumsum() - ALLOWANCE).clip_lower(0).diff().fillna(0)
0 0
1 0
2 20
3 30
dtype: float64
这是值
减去余量的累计总和。负值被剪裁为零(因为我们不关心数字,直到我们透支了我们的津贴)。从那里,你可以计算出差异
但是,如果第一个值可能大于公差,则最好采用以下两行变化:
s = (values.cumsum() - ALLOWANCE).clip_lower(0)
desired = s.diff().fillna(s)
这将用“第一个值-余量”值填充第一个NaN
值。因此,如果余量
降低到75,它将所需的
返回为系列([10,10,25,30])
谢谢。虽然这会起作用,但我也计划在pandas
中执行其他操作-因此,如果可能的话,我真的想要一个基于pandas
的解决方案。可能有更好的方法重写我的函数,我不是python专家,我想这可以使用生成器重写,但由于某种原因,它不太管用。理想情况下,如果容差已经为0,我会将其短路,并返回传入的行值。它确实为我指明了正确的方向,并给了我一些想法。。。非常感谢-现在阅读rolling\u apply
这似乎无法处理系列津贴的第一个元素的位置:(@JonClements您只需要附加.fillna(0)
@EdChum不能这么做-我想我需要使用类似于卡斯滕的答案,如果系列中的第一个值仍然是85
,而容差是70,结果是0
-这是不正确的-应该是15
我选择了你和卡斯滕的答案的混合-我喜欢剪辑(lower)()
在这篇文章中,尽管卡斯滕是第一个指出.fillna(0)
会产生不正确的结果的人。(尽管你已经纠正了这一点-谢谢)我会将值
变量重命名为费用
,将所需的
变量重命名为债务
,这与津贴
相结合,使读者不必看文本就能理解您想要完成的任务。