我处理中间具有空值的数据。我打算用特定列sales
的累积总和构建一个时间序列图。 sales
累积和的条件:(1.)如果第一行为空,fillna(0)
,则为cumsum()
,因此绘图始终可以从原点开始。 (2.)如果空行彼此跟随到结尾,则保留为null 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()
如何应用条件使结果变为:
答案 0 :(得分:4)
我们将使用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()
答案 1 :(得分:1)
所以我认为在制作数据帧之前最好先在字典中更改数据。执行此操作的最佳方法是以相反的顺序遍历列表,忽略所有None
值,直到满足第一个数值。在此之后,所有None
值都应更改为0
。
这不是处理这个问题的最佳方式,但它的编写方式易于阅读并理解它的作用。我相信这样会好得多。
flag = False
for sale in data["sales"][::-1]:
if !flag:
if sale:
flag = True
else
if !sale:
sale = 0
答案 2 :(得分:1)
更新: 您能否举例说明如何将您的解决方案作为功能实施?
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
原始回答:
你可以这样做:
首先设置为0
所有NaN&#39},但最后的除外:
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