使用pandas resample对特定的列进行重新采样

时间:2019-07-15 07:52:59

标签: python pandas resampling

以下是当前问题的简化。

我有一个数据帧,其中包含三列,状态开始的日期,状态本身和一个标志字段。它看起来类似于:

df = pd.DataFrame(
    {'begin': pd.to_datetime(['2018-01-05', '2018-07-11', '2018-11-14', '2019-02-19']),
    'state': [1, 2, 3, 4],
     'started': [1, 0, 0, 0]
     }
)

df

       begin  state  started
0 2018-01-05      1        1
1 2018-07-11      2        0
2 2018-11-14      3        0
3 2019-02-19      4        0

我想对日期重新采样,以使它们有一个月度周期,我实现了以下目标:

df.set_index('begin', drop=False).resample('m').ffill()

df 
                begin  state  started
begin                                
2018-01-31 2018-01-05      1        1
2018-02-28 2018-01-05      1        1
2018-03-31 2018-01-05      1        1
2018-04-30 2018-01-05      1        1
2018-05-31 2018-01-05      1        1
2018-06-30 2018-01-05      1        1
2018-07-31 2018-07-11      2        0
2018-08-31 2018-07-11      2        0
2018-09-30 2018-07-11      2        0
2018-10-31 2018-07-11      2        0
2018-11-30 2018-11-14      3        0
2018-12-31 2018-11-14      3        0
2019-01-31 2018-11-14      3        0
2019-02-28 2019-02-19      4        0

除了标志列(started)之外,其他所有内容都看起来不错。我需要将它第一次设为1,就像它在原始数据帧中第一次出现时一样。

所需的输出是:

                begin  state  started
begin                                
2018-01-31 2018-01-05      1        1
2018-02-28 2018-01-05      1        0
2018-03-31 2018-01-05      1        0
2018-04-30 2018-01-05      1        0
2018-05-31 2018-01-05      1        0
2018-06-30 2018-01-05      1        0
2018-07-31 2018-07-11      2        0
2018-08-31 2018-07-11      2        0
2018-09-30 2018-07-11      2        0
2018-10-31 2018-07-11      2        0
2018-11-30 2018-11-14      3        0
2018-12-31 2018-11-14      3        0
2019-01-31 2018-11-14      3        0
2019-02-28 2019-02-19      4        0

因此,对于beginstate的给定组合,如果started为1,则仅在该组合首次出现时才为一个。

有没有一种有效的方法来实现这一目标?

2 个答案:

答案 0 :(得分:1)

你能做吗

df = df.set_index('begin', drop=False).resample('m').ffill()
df.loc[df['started'].duplicated(keep='first'), 'started'] = 0

答案 1 :(得分:1)

如果仅GLcontext列中的10使用DataFrame.duplicated并在列表中指定两列:

started

还可以通过链接另一个掩码来仅重写mask = df.duplicated(['begin','started']) 值:

1

mask = df.duplicated(['begin','started']) & df['started'].eq(1)

或者:

df.loc[mask, 'started'] = 0