在Python中使用条件向后写入列
我有下面的df,希望向后写入数字列,并在必要时覆盖其他值。条件是始终使用以前的值,除非新值与旧值的差值大于10%在Python中使用条件向后写入列,python,pandas,Python,Pandas,我有下面的df,希望向后写入数字列,并在必要时覆盖其他值。条件是始终使用以前的值,除非新值与旧值的差值大于10% Date Number 2019 150 2018 NaN 2017 118 2016 NaN 2015 115 2014 107 2013 105 2012 NaN 2011 100 由于该条件,例如2013中的值等于100,因为该值不小于90且
Date Number
2019 150
2018 NaN
2017 118
2016 NaN
2015 115
2014 107
2013 105
2012 NaN
2011 100
由于该条件,例如2013中的值等于100,因为该值不小于90且不大于110。结果如下所示:
Date Number
2019 150
2018 115
2017 115
2016 115
2015 115
2014 100
2013 100
2012 100
2011 100
您可以反转列,然后应用函数更新值。最后,将列反转为原始顺序:
def get_val(x):
global prev_num
if x and x > prev_num*1.1:
prev_num = x
return prev_num
prev_num = 0
df['number'] = df['number'][::-1].apply(get_val)[::-1]
这里有一个方法。它假定第一个值100不是
NaN
,并且原始数据帧按年份递减。如果性能有问题,循环可以转换为列表理解
lst = df.sort_values('date')['number'].ffill().tolist()
for i in range(1, len(lst)):
if abs(lst[i] - lst[i-1]) / lst[i] <= 0.10:
lst[i] = lst[i-1]
df['number'] = list(reversed(lst))
# date number
# 0 2019 150.0
# 1 2018 115.0
# 2 2017 115.0
# 3 2016 115.0
# 4 2015 115.0
# 5 2014 100.0
# 6 2013 100.0
# 7 2012 100.0
# 8 2011 100.0
lst=df.sort_值('date')['number'].ffill().tolist()
对于范围(1,len(lst))中的i:
如果abs(lst[i]-lst[i-1])/lst[i]仅按地板除以10后的差值分组,该差值不等于零,则转换最小值,即
df['x'] = df.groupby((df['number'].bfill()[::-1]//10).diff().ne(0).cumsum())['number'].transform(min)
date number x
0 2019 150.0 150.0
1 2018 NaN 115.0
2 2017 118.0 115.0
3 2016 NaN 115.0
4 2015 115.0 115.0
5 2014 107.0 100.0
6 2013 105.0 100.0
7 2012 NaN 100.0
8 2011 100.0 100.0
对的我编辑了它,问题是什么?这很好,但我认为只有当这个数字随着时间的推移而变大时,它才起作用,也就是说,如果2019年的数字是50而不是150,会发生什么?是的,因为我在谈论差异,即(150-50)=100>15。@FriedrichFranz澄清如果是50而不是150,确切的输出是什么?如果2019年的数字是50,x也应该是50。对不起,我应该更清楚地说明这个例子,这是一个很好的解决方案。我的真实数据帧有几个不同的标识,我想对您的代码进行分组。但是,当我尝试:df['number']=df.groupby(“id”)['number'][::-1].apply(get_val)[::-1]
时,我得到异常:列号已被选中