以下是当前问题的简化。
我有一个数据帧,其中包含三列,状态开始的日期,状态本身和一个标志字段。它看起来类似于:
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
因此,对于begin
和state
的给定组合,如果started
为1,则仅在该组合首次出现时才为一个。
有没有一种有效的方法来实现这一目标?
答案 0 :(得分:1)
你能做吗
df = df.set_index('begin', drop=False).resample('m').ffill()
df.loc[df['started'].duplicated(keep='first'), 'started'] = 0
答案 1 :(得分:1)
如果仅GLcontext
列中的1
和0
使用DataFrame.duplicated
并在列表中指定两列:
started
还可以通过链接另一个掩码来仅重写mask = df.duplicated(['begin','started'])
值:
1
mask = df.duplicated(['begin','started']) & df['started'].eq(1)
或者:
df.loc[mask, 'started'] = 0