基于两列组合的匹配,将列从一个数据帧复制到另一数据帧

时间:2020-01-10 02:10:37

标签: python python-3.x pandas

我有两个数据帧(即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

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

time转换为timedelta并分配回df1。将INTERRUPTION_TIME转换为timedelta,并将floor转换为30分钟间隔,然后分配给s。按df2INCIDENT_DATEs分组并呼叫sum的{​​{1}}。最后,将WASTED_MINUTES的结果join返回到groupby

df1

答案 2 :(得分: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进行总结,然后再合并