首页 > 解决方案 > 前 N 行,直到找到值不为空

问题描述

我正在尝试实现一个简单的函数,该函数将允许我迭代返回以找到一个非空值,并且该值将存储在一个名为 prv_djma 的新列中。

数据

data = {'id_st': [100, 100, 100, 100, 100, 100, 100, 100, 100], 
    'year':  [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018],
    'djma':  [1000, 2200, 0, 3000, 1000, 0, 2000, 0, 0],
    'taux': [np.nan, 0.9, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 0.7]}

df = pd.DataFrame(data) 
df

在此处输入图像描述

df['prv_djma'] = df['djma'].shift()

在此处输入图像描述

我在找什么

在此处输入图像描述

目标是检查 N 行,直到找到不为空的 djma,然后将值放入当前行(列 prv_djma)。

例如,带有(索引 8)的最后一行有 djma=0,(索引 7)也是 djma=0,所以我想用 djma(索引 6)填充列 prv_djma。

笔记

我遇到的问题在索引 8 中。所有其他行都是正确的。

标签: pythonpandas

解决方案


这是shift,确保如果有连续的 0,我们将填充之前的值:

m = df.djma.eq(0)
df['prv_djma'] = df.djma.shift().mask((m == m.shift()) & m).ffill()

输出:

   id_st  year  djma  taux  prev_djma
0    100  2010  1000   NaN        NaN
1    100  2011  2200   0.9     1000.0
2    100  2012     0   1.1     2200.0
3    100  2013  3000   1.2        0.0
4    100  2014  1000   1.3     3000.0
5    100  2015     0   1.4     1000.0
6    100  2016  2000   1.5        0.0
7    100  2017     0   1.6     2000.0
8    100  2018     0   0.7     2000.0

对于组,您需要单独执行此操作,.shift以免溢出到组之外。

def get_prv(x):
    m = x.eq(0)
    return x.shift().mask((m == m.shift()) & m).ffill()

df['prv_djma'] = df.groupby('id_st')['djma'].apply(get_prv)

推荐阅读