[英]Pandas conditional cumulative sum
我正在使用介于两者之间为空值的数据。 我打算从特定列sales
的累积总和中构建时间序列图。 sales
累计金额的条件:(1.)如果第一行为null,则fillna(0)
,然后为cumsum()
因此绘图始终可以从原点开始。 (2.)如果空行紧随fillna(0)
,请保留为空,否则fillna(0)
:
data = {'year': [2010, 2011, 2012, 2013, 2014, 2015, 2016,2017, 2018, 2019],
'quantity': [10, 21, 20, 10, 39, 30, 31,45, 23, 56],
'sales': [None, 41, None, None, 32, 0, 31,None, None, None]}
df = pd.DataFrame(data)
df = df.set_index('year')
df['cum_sales'] = df[['sales']].cumsum()
print df
df.plot()
如何应用条件以使结果变为:
我们将结合使用bfill
和combine_first
。 当我们回填销售列时,我们会填写所有缺失值,后跟非缺失数据,从而满足条件(2)。 但是,我只用它来标识确实满足条件(2)的那些位置,因为我将把它们乘以零,然后用它来填充缺失的值。 我实际上并不想回填数据。 combine_first
首先从第一个数据帧中获取该值,如果丢失,它将尝试从第二个数据帧中获取该值。 因此,不满足条件2的缺失值将填充为零,否则将保持缺失。
关于以下内容的很多讨论:
df.sales = df.sales.combine_first(df.sales.bfill() * 0)
df.cum_sales = df.sales.cumsum()
print df
quantity sales cum_sales
year
2010 10 0.0 0.0
2011 21 41.0 41.0
2012 20 0.0 41.0
2013 10 0.0 41.0
2014 39 32.0 73.0
2015 30 0.0 73.0
2016 31 31.0 104.0
2017 45 NaN NaN
2018 23 NaN NaN
2019 56 NaN NaN
剧情:
df.plot()
因此,我认为最好在制作数据框之前先在字典中更改数据。 最佳方法是以相反的顺序遍历列表,忽略所有None
值,直到满足第一个数值。 在那之后,所有None
值都应更改为0
。
这不是解决此问题的最漂亮方法,但是它以易于阅读和理解的方式编写。 我相信这样会更好。
flag = False
for sale in data["sales"][::-1]:
if !flag:
if sale:
flag = True
else
if !sale:
sale = 0
更新: 您能否举一个例子,说明如何将您的解决方案实现为功能?
def set_col_last_valid(df, col, new_col):
df.loc[(df.index <= df[col].last_valid_index()) & (pd.isnull(df[col])), col] = 0
df[new_col] = df[col].cumsum()
return df
In [174]: new = set_col_last_valid(df, 'sales', 'cum_sales')
In [175]: new
Out[175]:
quantity sales cum_sales
year
2010 10 0.0 0.0
2011 21 41.0 41.0
2012 20 0.0 41.0
2013 10 0.0 41.0
2014 39 32.0 73.0
2015 30 0.0 73.0
2016 31 31.0 104.0
2017 45 NaN NaN
2018 23 NaN NaN
2019 56 NaN NaN
原始答案:
您可以这样操作:
首先,将所有NaN设置为0
,但末尾除外:
df.loc[(df.index <= df.sales.last_valid_index()) & (pd.isnull(df.sales)), 'sales'] = 0
现在您可以简单地使用cumsum()
In [142]: df.sales.cumsum()
Out[142]:
year
2010 0.0
2011 41.0
2012 41.0
2013 41.0
2014 73.0
2015 97.0
2016 128.0
2017 NaN
2018 NaN
2019 NaN
Name: sales, dtype: float64
说明:
In [154]: df.sales.last_valid_index()
Out[154]: 2016
In [155]: df.loc[df.index <= df.sales.last_valid_index()]
Out[155]:
quantity sales
year
2010 10 0.0
2011 21 41.0
2012 20 0.0
2013 10 0.0
2014 39 32.0
2015 30 24.0
2016 31 31.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.