python - 反转数据框中给定日期的时间

标签 python pandas datetime

对于包含开始和结束时间的数据框,我想“反转”给定日期的时间。肯定有一种“蛮力”方法可以通过循环遍历数据帧并有很多 if 条件来完成它,但我想知道是否有更优雅的方法,比如 backfill/forwardfill。

将其视为具有一个数据框,其中工作时间由具有开始和结束时间的行表示,而我最终想要的是该日期的空闲时间。 数据帧按单调递增的开始时间排序,并在日期更改时截止,因此时间从例如开始。 2019-04-04 22:00 和结束于 2019-04-05 04:00 由两行 2019-04-04 22:00 到 2019-04-05 00:00 和 2019-04-05 00:00 表示至 2019-04-05 04:00。这应该会使问题变得更容易。

示例代码:

import pandas as pd
import datetime

df = pd.DataFrame({'date': [datetime.date(2019, 4, 4), datetime.date(2019, 4, 5), datetime.date(2019, 4, 5)],
                   'start': [pd.Timestamp(2019, 4, 4, 10), pd.Timestamp(2019, 4, 5, 0), pd.Timestamp(2019, 4, 5, 14)],
                   'end': [pd.Timestamp(2019, 4, 4, 16), pd.Timestamp(2019, 4, 5, 4), pd.Timestamp(2019, 4, 5, 18)]})

所以从这里开始:

2019-04-04   2019-04-04 10:00:00   2019-04-04 16:00:00
2019-04-05   2019-04-05 00:00:00   2019-04-05 04:00:00
2019-04-05   2019-04-05 14:00:00   2019-04-05 18:00:00

我希望结果是这样的数据框:

2019-04-04   2019-04-04 00:00:00   2019-04-04 10:00:00
2019-04-04   2019-04-04 16:00:00   2019-04-05 00:00:00
2019-04-05   2019-04-05 04:00:00   2019-04-05 14:00:00
2019-04-05   2019-04-05 18:00:00   2019-04-06 00:00:00

非常感谢任何帮助。

最佳答案

您可以使用 shift 轻松完成此操作.问题出在最后一行,我正在尝试找出如何最好地重建。

编辑:我在最后一行尽了最大的努力,但最终却变得一团糟。对于最后一行的任何反馈,我会很高兴。原则上,使用 shift 会使这变得非常容易。显然,您可以在添加最后一行之前删除 startend,我只是展示了如何在不丢失数据的情况下执行此操作。

import pandas as pd
import numpy as np
import datetime as dt

df = pd.DataFrame({'date': [dt.date(2019, 4, 4), dt.date(2019, 4, 5), dt.date(2019, 4, 5)],
                   'start': [pd.Timestamp(2019, 4, 4, 10), pd.Timestamp(2019, 4, 5, 0), pd.Timestamp(2019, 4, 5, 14)],
                   'end': [pd.Timestamp(2019, 4, 4, 16), pd.Timestamp(2019, 4, 5, 4), pd.Timestamp(2019, 4, 5, 18)]})

df = df[['date', 'start', 'end']]

saved_shift_ending = df['end'].iloc[-1]  # we want end of last shift
saved_end_date = df['date'].iloc[-1]     # we also want the date value

start_date = df['date'].min()
end_date = (df['date'].max() + dt.timedelta(days=1))

df['other_start'] = df['end'].shift(1)
df['other_end'] = df['start']

df.loc[0, 'other_start'] = start_date # The first value is NaT after shift

last_row = pd.DataFrame([[saved_end_date.strftime('%Y-%m-%d'), 
                         np.nan, 
                         np.nan, 
                         saved_shift_ending, 
                         end_date]],
                        columns=['date', 'start', 'end', 'other_start',
                                'other_end'])

df = df.append(last_row)

df.drop(['start', 'end'], axis=1, inplace=True)
print(df)

关于python - 反转数据框中给定日期的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55541273/

相关文章:

python - 无法加入指定参数的 pandas 数据框

r - 在R中解析ISO8601

python - 在ipython终端窗口点击生成MouseEvenT类型.MOUSE_DOWN异常

java - 用于 java 的 LXML E 构建器?

python - 有人可以解释这个 if 语句是如何工作的吗?

python - Selenium webdriver 无需制作电脑服务器

Python - Pandas读取sql修改浮点值列

python - 如何按列的值对 pandas 数据框的行进行分组?

r - 在没有时区的 R 中创建日期和时间序列

c# - C#计算相对时间