熊猫N次向前填充值

时间:2019-05-24 14:20:58

标签: python pandas

我有一个带有1和0的数据框,如下所示(有关完整的可复制数据框,请参见下文):

2019-04-12 05:15:00  0
2019-04-12 05:30:00  1
2019-04-12 05:45:00  0
2019-04-12 06:00:00  1
2019-04-12 06:15:00  0
2019-04-12 06:30:00  0
2019-04-12 06:45:00  1
2019-04-12 07:00:00  0
2019-04-12 07:15:00  1
2019-04-13 01:30:00  1
2019-04-13 01:45:00  1
2019-04-13 02:00:00  1
2019-04-13 02:15:00  0
2019-04-13 02:30:00  0
2019-04-13 02:45:00  0
2019-04-13 03:00:00  0

我有一种方法可以将n_exit = 5次填充非零值:

n_exit = 5
sig.where(sig.ne(sig.shift()) & (sig == 1)).ffill(limit=n_exit).fillna(0, downcast='int')

上面的代码将给出以下内容:

2019-04-12 05:15:00  0.0
2019-04-12 05:30:00  1.0
2019-04-12 05:45:00  1.0
2019-04-12 06:00:00  1.0
2019-04-12 06:15:00  1.0
2019-04-12 06:30:00  1.0
2019-04-12 06:45:00  1.0
2019-04-12 07:00:00  1.0
2019-04-12 07:15:00  1.0
2019-04-13 01:30:00  1.0
2019-04-13 01:45:00  1.0
2019-04-13 02:00:00  1.0
2019-04-13 02:15:00  1.0
2019-04-13 02:30:00  1.0
2019-04-13 02:45:00  0.0
2019-04-13 03:00:00  0.0

这不是我想要的。 1上的2019-04-12 06:45:00应该被忽略,因为它在从n_exit = 5开始的1信号的2019-04-12 05:30:00

我想要的是:

2019-04-12 05:15:00  0
2019-04-12 05:30:00  1
2019-04-12 05:45:00  1
2019-04-12 06:00:00  1
2019-04-12 06:15:00  1
2019-04-12 06:30:00  1
2019-04-12 06:45:00  1
2019-04-12 07:00:00  0
2019-04-12 07:15:00  1
2019-04-13 01:30:00  1
2019-04-13 01:45:00  1
2019-04-13 02:00:00  1
2019-04-13 02:15:00  1
2019-04-13 02:30:00  1
2019-04-13 02:45:00  0
2019-04-13 03:00:00  0

解决此问题的一种可能方法是将1五次后的值替换为np.nan。从那里我们可以运行我的代码。但不确定如何执行此操作。

from pandas import Timestamp
sig = pd.DataFrame({1L: {Timestamp('2019-04-12 01:30:00'): 0L,
  Timestamp('2019-04-12 01:45:00'): 0L,
  Timestamp('2019-04-12 02:00:00'): 0L,
  Timestamp('2019-04-12 02:15:00'): 0L,
  Timestamp('2019-04-12 02:30:00'): 0L,
  Timestamp('2019-04-12 02:45:00'): 0L,
  Timestamp('2019-04-12 03:00:00'): 0L,
  Timestamp('2019-04-12 03:15:00'): 0L,
  Timestamp('2019-04-12 03:30:00'): 0L,
  Timestamp('2019-04-12 05:15:00'): 0L,
  Timestamp('2019-04-12 05:30:00'): 1L,
  Timestamp('2019-04-12 05:45:00'): 0L,
  Timestamp('2019-04-12 06:00:00'): 1L,
  Timestamp('2019-04-12 06:15:00'): 0L,
  Timestamp('2019-04-12 06:30:00'): 0L,
  Timestamp('2019-04-12 06:45:00'): 1L,
  Timestamp('2019-04-12 07:00:00'): 0L,
  Timestamp('2019-04-12 07:15:00'): 1L,
  Timestamp('2019-04-13 01:30:00'): 1L,
  Timestamp('2019-04-13 01:45:00'): 1L,
  Timestamp('2019-04-13 02:00:00'): 1L,
  Timestamp('2019-04-13 02:15:00'): 0L,
  Timestamp('2019-04-13 02:30:00'): 0L,
  Timestamp('2019-04-13 02:45:00'): 0L,
  Timestamp('2019-04-13 03:00:00'): 0L,
  Timestamp('2019-04-13 03:15:00'): 0L,
  Timestamp('2019-04-13 03:30:00'): 0L,
  Timestamp('2019-04-13 05:15:00'): 0L,
  Timestamp('2019-04-13 05:30:00'): 0L,
  Timestamp('2019-04-13 05:45:00'): 1L,
  Timestamp('2019-04-13 06:00:00'): 1L,
  Timestamp('2019-04-13 06:15:00'): 1L,
  Timestamp('2019-04-13 06:30:00'): 0L,
  Timestamp('2019-04-13 06:45:00'): 0L,
  Timestamp('2019-04-13 07:00:00'): 0L,
  Timestamp('2019-04-13 07:15:00'): 0L}}
)

2 个答案:

答案 0 :(得分:1)

我可能为此感到很生气,但是当我发现某些东西太复杂而无法在熊猫中轻松表达时,我会在底层的numpy数组上恢复到古老的普通Python方式。

它可能没有真正向量化操作的效率高,但由于它仅对numpy数组进行迭代,因此它仍然比熊猫迭代的速度快得多。在这里我会用:

new_col = np.zeros(len(sig)).astype(np.int64)
state = 0
for i, val in enumerate(sig.iloc[:, 0].values):
    if state == 0:
        if val == 1:
            state = 5
            new_col[i] = 1
    else:
        new_col[i] = 1
        state -= 1

sig['new_col'] = new_col   

它给出:

                     1  new_col
2019-04-12 01:30:00  0        0
2019-04-12 01:45:00  0        0
2019-04-12 02:00:00  0        0
2019-04-12 02:15:00  0        0
2019-04-12 02:30:00  0        0
2019-04-12 02:45:00  0        0
2019-04-12 03:00:00  0        0
2019-04-12 03:15:00  0        0
2019-04-12 03:30:00  0        0
2019-04-12 05:15:00  0        0
2019-04-12 05:30:00  1        1
2019-04-12 05:45:00  0        1
2019-04-12 06:00:00  1        1
2019-04-12 06:15:00  0        1
2019-04-12 06:30:00  0        1
2019-04-12 06:45:00  1        1
2019-04-12 07:00:00  0        0
2019-04-12 07:15:00  1        1
2019-04-13 01:30:00  1        1
2019-04-13 01:45:00  1        1
2019-04-13 02:00:00  1        1
2019-04-13 02:15:00  0        1
2019-04-13 02:30:00  0        1
2019-04-13 02:45:00  0        0
2019-04-13 03:00:00  0        0
2019-04-13 03:15:00  0        0
2019-04-13 03:30:00  0        0
2019-04-13 05:15:00  0        0
2019-04-13 05:30:00  0        0
2019-04-13 05:45:00  1        1
2019-04-13 06:00:00  1        1
2019-04-13 06:15:00  1        1
2019-04-13 06:30:00  0        1
2019-04-13 06:45:00  0        1
2019-04-13 07:00:00  0        1
2019-04-13 07:15:00  0        0

正确忽略2019-04-12 06:45:00处的1

答案 1 :(得分:-1)

您的代码存在的问题是0NaN不同。测试答案很困难,因为填充数据框的代码无法正常工作,而且我也无需进行故障排除。

基本上,您使用了三个独立的错误代码段来尝试做同样的事情。我在下面编写的解决方案应该按照您在问题中描述的方式工作。我必须根据您的代码sig['ne']做一些假设,列为1和0。

 # First remove 0 values
 from numpy import nan
 mask = (sig == 0)
 sig.loc[mask] = nan

 # Then ffill as you originally intended.
 sig = sig.fillna(method='ffill',limit=5)

 # Finally, add back the other 0s
 sig = sig.fillna(0)