1

我有两个数据框(即 df1 和 df2)。

df1 包含日期和时间列。时间列包含 30 分钟间隔的时间序列:

df1:
         date      time
0       2015-04-01  00:00:00
1       2015-04-01  00:30:00
2       2015-04-01  01:00:00
3       2015-04-01  01:30:00
4       2015-04-01  02:00:00

df2 包含日期、开始时间、结束时间、值:

df2
       INCIDENT_DATE INTERRUPTION_TIME RESTORE_TIME  WASTED_MINUTES
0        2015-04-01             00:32        01:15          1056.0
1        2015-04-01             01:20        02:30          3234.0
2        2015-04-01             01:22        03:30          3712.0
3        2015-04-01             01:30        03:15          3045.0

现在,当两个数据帧的日期列相同且 df2 列的 Interruption_time 位于 df1 的时间列时,我想将 wasted_minutes 列从 df2 复制到 df1。所以输出应该是这样的:

df1:
                date      time      Wasted_columns
    0       2015-04-01  00:00:00       NaN
    1       2015-04-01  00:30:00       1056.0
    2       2015-04-01  01:00:00       6946.0
    3       2015-04-01  01:30:00       3045.0
    4       2015-04-01  02:00:00       NaN

我尝试了合并命令(基于日期列),但没有产生预期的结果,因为我不确定如何检查时间是否以 30 分钟为间隔?谁能指导如何解决这个问题?

4

3 回答 3

1

你可以这样做

df1['time']=pd.to_datetime(df1['time'])
df1['Wasted_columns']=df1.apply(lambda x: df2.loc[(pd.to_datetime(df2['INTERRUPTION_TIME'])>= x['time']) & (pd.to_datetime(df2['INTERRUPTION_TIME'])< x['time']+pd.Timedelta(minutes=30)),'WASTED_MINUTES'].sum(), axis=1)
df1['time']=df1['time'].dt.time

如果您在 lambda 函数本身中转换“时间”列,那么它只是一行代码,如下所示

df1['Wasted_columns']=df1.apply(lambda x: df2.loc[(pd.to_datetime(df2['INTERRUPTION_TIME'])>= pd.to_datetime(x['time'])) & (pd.to_datetime(df2['INTERRUPTION_TIME'])< pd.to_datetime(x['time'])+pd.Timedelta(minutes=30)),'WASTED_MINUTES'].sum(), axis=1)

输出

          date     time     Wasted_columns
0   2015-04-01  00:00:00    0.0
1   2015-04-01  00:30:00    1056.0
2   2015-04-01  01:00:00    6946.0
3   2015-04-01  01:30:00    3045.0
4   2015-04-01  02:00:00    0.0
于 2020-01-10T03:45:49.573 回答
1

转换time为 timedelta 并分配回df1. 转换INTERRUPTION_TIME为 timedelta 并将floor其转换为 30 分钟间隔并分配给s. Groupby df2byINCIDENT_DATEscall sumof WASTED_MINUTES。最后返回join结果groupbydf1

df1['time'] = pd.to_timedelta(df1['time'].astype(str)) #cast to str before calling `to_timedelta`
s = pd.to_timedelta(df2.INTERRUPTION_TIME+':00').dt.floor('30Min')
df_final = df1.join(df2.groupby(['INCIDENT_DATE', s]).WASTED_MINUTES.sum(), 
                    on=['date', 'time'])

Out[631]:
         date     time  WASTED_MINUTES
0  2015-04-01 00:00:00             NaN
1  2015-04-01 00:30:00          1056.0
2  2015-04-01 01:00:00          6946.0
3  2015-04-01 01:30:00          3045.0
4  2015-04-01 02:00:00             NaN
于 2020-01-10T06:06:50.737 回答
0

想法:+转换为日期时间+四舍五入到最近的30分钟+合并

from datetime import datetime, timedelta

def ceil_dt(dt, delta):
    return dt + (datetime.min - dt) % delta

# Convert
df1['dt'] = (df1['date'] + ' ' + df1['time']).apply(datetime.strptime, args=['%Y-%m-%d %H:%M:%S'])
df2['dt'] = (df2['INCIDENT_DATE '] + ' ' + df2['INTERRUPTION_TIME']).apply(datetime.strptime, args=['%Y-%m-%d %H:%M'])

# Round
def ceil_dt(dt, delta):
    return dt + (datetime.min - dt) % delta

df2['dt'] = df2['dt'].apply(ceil_dt, args=[timedelta(minutes=30)])

# Merge
final = df1.merge(df2.loc[:, ['dt', 'wasted_column'], on='dt', how='left'])

此外,如果在 30 分钟的时间范围内发生多起事件,您可能希望先在 df2 上进行分组,并首先使用舍入的 dt col 总结浪费然后合并

于 2020-01-10T03:57:39.347 回答