熊猫条件累积和

时间:2016-06-02 19:57:45

标签: python pandas

我处理中间具有空值的数据。我打算用特定列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()

enter image description here

如何应用条件使结果变为:

enter image description here

3 个答案:

答案 0 :(得分:4)

我们将使用bfillcombine_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()

enter image description here

答案 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