#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())