<p>roganjosh回答了一般情况,但是我必须查看每天的“空闲时间”,为此我必须添加一些人工日期边界,作为开始和结束之间时间为零的行。最后<code>.shift()</code>就是我想要的。
我把它打包成一个函数来增加可重用性,如果有人有更优雅的解决方案,请随意分享。你知道吗</p>
<p>这是我的密码:</p>
<pre><code>def invertDailyTimes(df, dateCol, starttimeCol, endtimeCol):
"""
requires a input df with a date column (dateCol) and two timestamp columns (starttimeCol, endttimeCol)
which is monotonic ordered in (starttimeCol, endttimeCol)
"""
dates = list(df[dateCol].unique())
for d in dates:
df_tmp = df[df[dateCol] == d].iloc[0:1]
df_tmp[starttimeCol] = pd.Timestamp(d)
df_tmp[endtimeCol] = pd.Timestamp(d)
df_tmp = df_tmp.append(df_tmp)
df_tmp[starttimeCol].iloc[-1] = pd.Timestamp(d + datetime.timedelta(days=1))
df_tmp[endtimeCol].iloc[-1] = pd.Timestamp(d + datetime.timedelta(days=1))
df_tmp[dateCol].iloc[-1] = d + datetime.timedelta(days=1)
df = df.append(df_tmp)
df.drop_duplicates(inplace=True)
df.sort_values(by=[starttimeCol, endtimeCol], inplace=True)
df['invert_start'] = df[endtimeCol].shift(1)
df['invert_end'] = df[starttimeCol]
df = df[(abs(df['invert_start'] - df['invert_end']) < pd.Timedelta(days=1)) &
(abs(df['invert_start'] - df['invert_end']) > pd.Timedelta(seconds=0))]
df[starttimeCol] = df['invert_start']
df[endtimeCol] = df['invert_end']
df.drop(columns=['invert_start', 'invert_end'], inplace=True)
return df
</code></pre>