Панды, объединяющие два фрейма данных с объединением по дате между датами

#python #pandas #datetime #merge #timedelta

#python #pandas #дата-время #слияние #timedelta

Вопрос:

Есть довольно интересный случай.

Существует столбец df_1 with time , основанный на данных с низкой степенью детализации (2s), подобный этому:

 2018-08-31 22:59:47.980000 00:00    41.77   
2018-08-31 22:59:49.979000 00:00    42.76   
2018-08-31 22:59:51.979000 00:00    40.86   
2018-08-31 22:59:53.979000 00:00    41.83   
2018-08-31 22:59:55.979000 00:00    41.73   
2018-08-31 22:59:57.979000 00:00    42.71
  

Также есть df_2 с метками для этих данных и time столбцом на основе часов:

 2018-08-31 22:00:00 0.0
2018-08-31 23:00:00 1.0
2018-09-01 00:00:00 0.0
2018-09-01 01:00:00 1.0
2018-09-01 02:00:00 0.0
  

Я хотел бы объединить, df_1 учитывая df_2 , что время из df_1 было бы между каждыми двумя последовательными временными рядами в df_2 (между одним часом для присвоения метки). Если бы у меня было два столбца времени в df_2 (например, startTime и endTime ), я бы использовал pandasql и его возможности:

 import pandasql 

sqlcode = '''
select *
from df_1
inner join df_2 on df_1.time >= df_2.startTime and df_1.time <= df_2.endTime
'''

newdf = ps.sqldf(sqlcode,locals())
  

Но в этом случае у меня есть только один столбец. Есть ли какой-либо способ решить эту проблему в Pandas?

Комментарии:

1. Не могли бы вы добавить скриншоты в качестве образца данных в свой вопрос, чтобы мы могли скопировать?

2. Можете ли вы показать нам свои образцы данных? (не фото)

3. Если вы собираетесь подсчитывать, используйте повторную выборку по часам.

4. нет проблем, просто добавлены значения

5. обновил сообщение

Ответ №1:

Это pd.merge_asof проблема, я создаю keydat, состоящий из двух дат в df2, чтобы показать, какую дату мы объединяем из df2

 #df1.Date=pd.to_datetime(df1.Date)
#df2.Date=pd.to_datetime(df2.Date)
yourdf=pd.merge_asof(df1,df2.assign(keydate=df2.Date),on='Date',direction='forward')
yourdf
                     Date         ...                     keydate
0 2018-08-31 22:59:47.980         ...         2018-08-31 23:00:00
1 2018-08-31 22:59:49.979         ...         2018-08-31 23:00:00
2 2018-08-31 22:59:51.979         ...         2018-08-31 23:00:00
3 2018-08-31 22:59:53.979         ...         2018-08-31 23:00:00
4 2018-08-31 22:59:55.979         ...         2018-08-31 23:00:00
5 2018-08-31 22:59:57.979         ...         2018-08-31 23:00:00
[6 rows x 4 columns]
  

Комментарии:

1. Я думаю, проблема в том, что существует интервал в 2 секунды и merge_asof здесь не подойдет. Если это будет 1 с, то да, я думаю, это можно использовать

2. @Keithx проверьте допуск в нем и передайте ваше условие 2 s 🙂

Ответ №2:

Я решил проблему, используя обходной путь с разделением времени на date и hour столбцы. Может быть, не слишком причудливо, но это решает проблему и довольно прямолинейно:

 import pandasql as ps

df_1['date'] = [d.date() for d in df_1['time']]
df_1['time'] = df_1['time'].dt.round('H').dt.hour

df_2['date'] = [d.date() for d in df_2['time']]
df_2['time'] = df_2['time'].dt.round('H').dt.hour

sqlcode = '''
select *
from df_1
inner join df_2 on df_1.time=df_2.time and df_1.date=df_2.date
'''

newdf = ps.sqldf(sqlcode,locals())