Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用条件向后写入列_Python_Pandas - Fatal编程技术网

在Python中使用条件向后写入列

在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且

我有下面的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且不大于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]
时,我得到异常:列号已被选中