Панды: навязывать временную шкалу даты-времени из одного кадра данных в другой. - PullRequest
2 голосов
/ 06 апреля 2019

У меня есть 2 данных кадра:

main_df:

    value    feed_id                created_at  
0     0.0  1010077.0 2019-03-06 07:38:18-05:00   
1     1.0  1010077.0 2019-03-06 07:39:26-05:00   
2     1.0  1010077.0 2019-03-06 07:40:33-05:00   
3     1.0  1010077.0 2019-03-06 07:41:41-05:00   
4     1.0  1010077.0 2019-03-06 07:42:49-05:00   
5     1.0  1010077.0 2019-03-06 07:43:56-05:00   

aux_df:

       value    feed_id                created_at
0  20.298492  1009408.0 2019-03-06 07:35:33-05:00
1  20.315002  1009408.0 2019-03-06 07:36:34-05:00
2  20.315002  1009408.0 2019-03-06 07:37:36-05:00
3  20.359650  1009408.0 2019-03-06 07:38:36-05:00
4  20.359650  1009408.0 2019-03-06 07:39:37-05:00
5  20.383179  1009408.0 2019-03-06 07:40:38-05:00
6  20.383179  1009408.0 2019-03-06 07:41:38-05:00
7  20.449524  1009408.0 2019-03-06 07:42:39-05:00
8  20.449524  1009408.0 2019-03-06 07:43:40-05:00
9  20.521912  1009408.0 2019-03-06 07:44:41-05:00

Мне нужно следующее (final_df) при этом условии: я хочу, чтобы «временная шкала», описанная в столбце «create_at» из aux_df, была полностью объединена с main_df, независимо от того, имеет ли она общие или не общие значения в обоих столбцах. Для обычных я беру целую отметку времени и игнорирую часть в секундах (обратите внимание, как все значения выровнены по одной и той же дате, часам и минутам, но не секундам ).

       value    feed_id                created_at
0        nan        nan 2019-03-06 07:35:33-05:00
1        nan        nan 2019-03-06 07:36:34-05:00
2        nan        nan 2019-03-06 07:37:36-05:00
3        0.0  1010077.0 2019-03-06 07:38:36-05:00
4        1.0  1010077.0 2019-03-06 07:39:37-05:00
5        1.0  1010077.0 2019-03-06 07:40:38-05:00
6        1.0  1010077.0 2019-03-06 07:41:38-05:00
7        1.0  1010077.0 2019-03-06 07:42:39-05:00
8        1.0  1010077.0 2019-03-06 07:43:40-05:00
9        nan        nan 2019-03-06 07:44:41-05:00

Стратегия, которую я попробовал, но не удалось:

  1. Создайте новый столбец на обоих фреймах данных с именем 'selected_at_2', используя «округлять» по минутам на каждой отметке времени, чтобы я мог просто отбросить секунд часть на отметке времени, прежде чем я сделаю слияние.
  2. Использовать слияние.

    main_df ['made_at_2'] = main_df.created_at.dt.round ('min') aux_df ['made_at_2'] = aux_df.created_at.dt.round ('min') final_df = pd.merge (main_df, aux_df, on = ['made_at_2'], how = 'inner')

Но этот метод не является надежным, как указано в этом примере. Когда вы округляете метки времени, например 2019-03-06 07: 40: 33-05: 00, вы получите 41 минуту вместо 40. И мне нужен непрерывный поминутный столбец.

Я мог бы просто переформатировать временную метку, используя это:

main_df.created_at.map(lambda t: t.strftime('%Y-%m-%d %H:%M'))
aux_df.created_at.map(lambda t: t.strftime('%Y-%m-%d %H:%M'))
final_df = pd.merge(main_df, aux_df, on=['created_at_2'], how='inner')

Но не уверен, что этот метод является надежным, и мне все равно нужно индексировать значения, которые не являются общими для столбца «create_at». Итак, есть ли более правильный способ достичь этого?

Заранее спасибо!

1 Ответ

1 голос
/ 06 апреля 2019

Одна идея - использовать merge_asof, но последняя строка отличается:

main_df['created_at'] = pd.to_datetime(main_df['created_at'])
aux_df['created_at'] = pd.to_datetime(aux_df['created_at'])

df = pd.merge_asof(aux_df[['created_at']], main_df, on=['created_at'])
print (df)
                 created_at  value    feed_id
0 2019-03-06 07:35:33-05:00    NaN        NaN
1 2019-03-06 07:36:34-05:00    NaN        NaN
2 2019-03-06 07:37:36-05:00    NaN        NaN
3 2019-03-06 07:38:36-05:00    0.0  1010077.0
4 2019-03-06 07:39:37-05:00    1.0  1010077.0
5 2019-03-06 07:40:38-05:00    1.0  1010077.0
6 2019-03-06 07:41:38-05:00    1.0  1010077.0
7 2019-03-06 07:42:39-05:00    1.0  1010077.0
8 2019-03-06 07:43:40-05:00    1.0  1010077.0
9 2019-03-06 07:44:41-05:00    1.0  1010077.0

Другая - использовать Series.dt.floor вместо round:

main_df['created_at'] = pd.to_datetime(main_df['created_at'])
aux_df['created_at'] = pd.to_datetime(aux_df['created_at'])
main_df['created_at_2'] = main_df.created_at.dt.floor('min') 
aux_df['created_at_2'] = aux_df.created_at.dt.floor('min') 

df = pd.merge(aux_df[['created_at_2']], main_df, on=['created_at_2'], how='left')
print (df)
               created_at_2  value    feed_id                created_at
0 2019-03-06 07:35:00-05:00    NaN        NaN                       NaT
1 2019-03-06 07:36:00-05:00    NaN        NaN                       NaT
2 2019-03-06 07:37:00-05:00    NaN        NaN                       NaT
3 2019-03-06 07:38:00-05:00    0.0  1010077.0 2019-03-06 07:38:18-05:00
4 2019-03-06 07:39:00-05:00    1.0  1010077.0 2019-03-06 07:39:26-05:00
5 2019-03-06 07:40:00-05:00    1.0  1010077.0 2019-03-06 07:40:33-05:00
6 2019-03-06 07:41:00-05:00    1.0  1010077.0 2019-03-06 07:41:41-05:00
7 2019-03-06 07:42:00-05:00    1.0  1010077.0 2019-03-06 07:42:49-05:00
8 2019-03-06 07:43:00-05:00    1.0  1010077.0 2019-03-06 07:43:56-05:00
9 2019-03-06 07:44:00-05:00    NaN        NaN                       NaT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...