Как объединить строку в ближайшую строку (на основе отметки времени) в Pandas? - PullRequest
1 голос
/ 16 апреля 2020

Я относительно новичок в Pandas, поэтому мои искренние извинения, если мой вопрос не был правильно сформулирован, у меня есть набор данных здесь,

                       t  HVAC1_S1  HVAC2_S1  ...  HVAC4_S1  HVAC5_S1  HVAC6_S1
0       2009-08-18 18:12     711.0       0.0  ...       0.0       0.0       0.0
1       2009-08-18 18:14     705.0     734.0  ...       0.0     725.0     711.0
2       2009-08-18 18:15       0.0       0.0  ...     730.0       0.0       0.0
3       2009-08-18 18:29       0.0     721.0  ...     716.0     718.0     712.0
4       2009-08-18 18:30     705.0       0.0  ...       0.0       0.0       0.0
                 ...       ...       ...  ...       ...       ...       ...
156033  2012-11-09 21:59     714.0     720.0  ...     739.0       0.0     727.0
156034  2012-11-09 22:00       0.0       0.0  ...       0.0     743.0       0.0
156035  2012-11-09 22:14     723.0     729.0  ...     734.0     743.0     732.0
156036  2012-11-09 22:29     718.0     732.0  ...       0.0     739.0     725.0
156037  2012-11-09 22:30       0.0       0.0  ...     739.0       0.0       0.0

Так что, если вы заметите временную метку, например, индекс '1', т.е. в 2009-08-18 18:14 было выполнено 5 чтений (одно не видно из-за ...). Сейчас на самом деле есть 6 чтений, но последнее чтение было принято в следующую минуту, то есть в 2009-08-18 18:15. Ну, это немного сбивает с толку, потому что здесь нет секунд. Более того, все 6 показаний снимаются одновременно, а затем через 15 минут они измеряются снова. Теперь при измерении одно значение часто измеряется в следующую минуту, из-за чего оно находится в новой строке.

Я хочу установить допуск в 1 минуту и ​​объединить значение таких строк (как в индексе 2, 4, 156034, 156037) к предыдущим строкам и удалите эту строку из фрейма данных

, например, например, я хотел бы получить свой фрейм данных как

                       t  HVAC1_S1  HVAC2_S1  ...  HVAC4_S1  HVAC5_S1  HVAC6_S1
0       2009-08-18 18:12     711.0       0.0  ...       0.0       0.0       0.0
1       2009-08-18 18:14     705.0     734.0  ...      730.0     725.0     711.0
2       2009-08-18 18:29     705.0     721.0  ...     716.0     718.0     712.0
                 ...       ...       ...  ...       ...       ...       ...
156033  2012-11-09 21:59     714.0     720.0  ...     739.0     743.0     727.0
156035  2012-11-09 22:14     723.0     729.0  ...     734.0     743.0     732.0
156036  2012-11-09 22:29     718.0     732.0  ...     739.0     739.0     725.0

Примечание: индекс 0 может быть пренебрегли, потому что это из-за допуска 1 мин.

, пожалуйста, предоставьте ваше ценное предложение. Спасибо!

1 Ответ

1 голос
/ 17 апреля 2020

Вы можете использовать объединение asof для объединения DataFrame с самим собой. Выберите направление вперед и не допускайте точных совпадений (иначе одна и та же строка всегда будет сливаться с собой). Мы можем указать допуск в 1 минуту. Нам нужно привести индекс в слияние, чтобы мы могли удалить строки, которые слились с другими после слияния.

После слияния у нас будут столбцы _x и _y, мы можем удалить их и сгруппировать вдоль оси столбцов, чтобы объединить их.

Входные данные:

                    t  HVAC1_S1  HVAC2_S1  HVAC4_S1  HVAC5_S1  HVAC6_S1
0 2009-08-18 18:12:00     711.0       0.0       0.0       0.0       0.0
1 2009-08-18 18:14:00     705.0     734.0       0.0     725.0     711.0
2 2009-08-18 18:15:00       0.0       0.0     730.0       0.0       0.0
3 2009-08-18 18:29:00       0.0     721.0     716.0     718.0     712.0
4 2009-08-18 18:30:00     705.0       0.0       0.0       0.0       0.0

Код:

import pandas as pd
#df['t'] = pd.to_datetime(df['t'])  #If not datetime

res = pd.merge_asof(df.reset_index(), df.reset_index(), 
                    on='t', 
                    direction='forward', 
                    allow_exact_matches=False,
                    tolerance=pd.Timedelta('1min'))
res = res.set_index('t')

res = res[~res.index_x.isin(res.index_y)]  #Remove rows that merged with others
res = res.drop(columns=['index_x', 'index_y'])

res = res.groupby(res.columns.str.rsplit('_', n=1).str[0], axis=1).sum()

Выход:

                     HVAC1_S1  HVAC2_S1  HVAC4_S1  HVAC5_S1  HVAC6_S1
t                                                                    
2009-08-18 18:12:00     711.0       0.0       0.0       0.0       0.0
2009-08-18 18:14:00     705.0     734.0     730.0     725.0     711.0
2009-08-18 18:29:00     705.0     721.0     716.0     718.0     712.0
...