首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于递减值计算新值

基于递减值计算新值
EN

Stack Overflow用户
提问于 2015-02-23 15:13:16
回答 4查看 859关注 0票数 14

问题:

我想要做的是一步一步地将Series中的值减少一个不断下降的基数。

我不知道这是什么术语--我确实认为我可以用cumsumdiff做点什么,但我想我是在白费力气.

启动代码:

代码语言:javascript
复制
import pandas as pd

ALLOWANCE = 100
values = pd.Series([85, 10, 25, 30])

期望输出:

代码语言:javascript
复制
desired = pd.Series([0, 0, 20, 30])

的基本原理:

ALLOWANCE的基数开始-- Series中的每个值都会减去剩余的金额,就像备抵本身一样,因此会发生以下步骤:

  • 从100开始,我们可以完全删除85,使其成为0,现在15ALLOWANCE的形式保留下来
  • 下一个值是10,我们仍然有可用的15,因此这个值再次变为0,并且还剩下5
  • 下一个值是25 --我们只剩下5了,所以这个值变成了20,现在我们没有进一步的备抵了。
  • 下一个值是30,由于没有备抵,所以这个值仍然是30
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-02-23 15:34:31

按照您最初对cumsumdiff的想法,您可以编写:

代码语言:javascript
复制
>>> (values.cumsum() - ALLOWANCE).clip_lower(0).diff().fillna(0)
0     0
1     0
2    20
3    30
dtype: float64

这是values减去免税额的累计总和。负值被裁剪为零(因为我们不关心数字,直到我们透支了我们的津贴)。从那里,你可以计算出差异。

但是,如果第一个值可能大于津贴,则最好采用以下两行差异:

代码语言:javascript
复制
s = (values.cumsum() - ALLOWANCE).clip_lower(0)
desired = s.diff().fillna(s)

这将使用“第一个值-允许”值填充第一个NaN值。因此,在ALLOWANCE降低到75的情况下,它以Series([10, 10, 25, 30])的形式返回desired

票数 10
EN

Stack Overflow用户

发布于 2015-02-23 15:33:54

你对cumsumdiff的想法是可行的。它看起来并不复杂;不确定是否有更短的解决方案。首先,我们计算累积和,对其进行运算,然后返回(diffcumsum的反函数)。

代码语言:javascript
复制
import math

c = values.cumsum() - ALLOWANCE
# now we've got [-15, -5, 20, 50]
c[c < 0] = 0 # negative values don't make sense here

# (c - c.shift(1)) # <-- what I had first: diff by accident

# it is important that we don't fill with 0, in case that the first
# value is greater than ALLOWANCE
c.diff().fillna(math.max(0, values[0] - ALLOWANCE))
票数 8
EN

Stack Overflow用户

发布于 2015-02-23 15:28:36

这可能不是很好的表现,但目前这是一种使用rolling_apply的Pandas方式

代码语言:javascript
复制
In [53]:

ALLOWANCE = 100
def reduce(x):
    global ALLOWANCE
    # short circuit if we've already reached 0
    if ALLOWANCE == 0:
        return x
    val = max(0, x - ALLOWANCE)
    ALLOWANCE = max(0, ALLOWANCE - x)
    return val

pd.rolling_apply(values, window=1, func=reduce)
Out[53]:
0     0
1     0
2    20
3    30
dtype: float64

或者更简单地说:

代码语言:javascript
复制
In [58]:

values.apply(reduce)
Out[58]:
0     0
1     0
2    20
3    30
dtype: int64
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28676916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档