Панды: получить наблюдения по метке времени

Matthias спросил: 13 октября 2017 в 06:47 в: python

Я получил список динамических значений (например, наблюдения). Он записывает все изменения значений объекта (например, отображение).

df
+----+---------------------+-----------------+---------+
|    | time                |   display_index | value   |
|----+---------------------+-----------------+---------|
|  0 | 2017-11-06 13:00:00 |               1 | val1    |
|  1 | 2017-11-06 14:00:00 |               1 | val2    |
|  2 | 2017-11-06 15:00:00 |               1 | val1    |
|  3 | 2017-11-06 13:30:00 |               2 | val3    |
|  4 | 2017-11-06 14:05:00 |               2 | val4    |
|  5 | 2017-11-06 15:30:00 |               2 | val1    |
+----+---------------------+-----------------+---------+

Теперь у меня есть второй список временных меток, и меня интересуют значения, которые отображались на каждом дисплее. время. Обратите внимание, что первая временная метка (13:00) для display_index 2 раньше, чем будет известно какое-либо значение для этой переменной (первая запись - 13:30).

df_times
+----+---------------------+-----------------+
|    | time                |   display_index |
|----+---------------------+-----------------|
|  0 | 2017-11-06 13:20:00 |               1 |
|  1 | 2017-11-06 13:40:00 |               1 |
|  2 | 2017-11-06 13:00:00 |               2 |
|  3 | 2017-11-06 14:00:00 |               2 |
+----+---------------------+-----------------+

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

df_merged = df_times.merge(df, on='display_index', how='outer', suffixes=['','_measured'])
df_merged['seconds'] = (df_merged.time_measured - df_merged.time).astype('timedelta64[s]')
df_merged['seconds'] = df_merged['seconds'].apply(math.fabs)
df_merged = df_merged.sort_values('seconds').groupby(['time', 'display_index'], as_index=False).first()
print(tabulate(df_merged, headers='keys', tablefmt='psql'))+----+---------------------+-----------------+---------------------+---------+-----------+
|    | time                |   display_index | time_measured       | value   |   seconds |
|----+---------------------+-----------------+---------------------+---------+-----------|
|  0 | 2017-11-06 13:00:00 |               2 | 2017-11-06 13:30:00 | val3    |      1800 |
|  1 | 2017-11-06 13:20:00 |               1 | 2017-11-06 13:00:00 | val1    |      1200 |
|  2 | 2017-11-06 13:40:00 |               1 | 2017-11-06 14:00:00 | val2    |      1200 |
|  3 | 2017-11-06 14:00:00 |               2 | 2017-11-06 14:05:00 | val4    |       300 |
+----+---------------------+-----------------+---------------------+---------+-----------+

Проблема в том, что последний значения для дисплея 1 и 2 неверны, так как они все еще показывают другое значение в то время. Это должно быть val1 для дисплея 1 и val3 для дисплея 2. То, что я на самом деле ищу, это наблюдение, которое в последний раз видели перед отметкой времени. Так как это сделать?

Вот код, который я использовал:

import pandas as pd
from tabulate import tabulate
import mathvalues = [("2017-11-06 13:00", 1, 'val1'),
          ("2017-11-06 14:00", 1, 'val2'),
          ("2017-11-06 15:00", 1, 'val1'),
          ("2017-11-06 13:30", 2, 'val3'),
          ("2017-11-06 14:05", 2, 'val4'),
          ("2017-11-06 15:30", 2, 'val1'),
         ]
labels = ['time', 'display_index', 'value']
df = pd.DataFrame.from_records(values, columns=labels)
df['time'] = pd.to_datetime(df['time']) 
print(tabulate(df, headers='keys', tablefmt='psql'))values = [("2017-11-06 13:20", 1),
          ("2017-11-06 13:40", 1),
          ("2017-11-06 13:00", 2),
          ("2017-11-06 14:00", 2),
         ]
labels = ['time', 'display_index']
df_times = pd.DataFrame.from_records(values, columns=labels)
df_times['time'] = pd.to_datetime(df_times['time']) 
print(tabulate(df_times, headers='keys', tablefmt='psql'))df_merged = df_times.merge(df, on='display_index', how='outer', suffixes=['','_measured'])
df_merged['seconds'] = (df_merged.time_measured - df_merged.time).astype('timedelta64[s]')
df_merged['seconds'] = df_merged['seconds'].apply(math.fabs)
df_merged = df_merged.sort_values('seconds').groupby(['time', 'display_index'], as_index=False).first()
print(tabulate(df_merged, headers='keys', tablefmt='psql'))


0 ответов