Pandas эффективно переиндексирует и интерполирует временные ряды (переиндексация отбрасывает данные) - PullRequest
0 голосов
/ 08 октября 2018

Предположим, я хочу переиндексировать, с линейной интерполяцией, временной ряд к заранее определенному индексу, где ни одно из значений индекса не будет разделено между старым и новым индексом.Например,

# index is all precise timestamps e.g. 2018-10-08 05:23:07
series = pandas.Series(data,index) 

# I want rounded date-times
desired_index = pandas.date_range("2010-10-08",periods=10,freq="30min") 

Учебники / API предлагают способ сделать это - reindex, а затем заполнить значения NaN, используя interpolate.Но, поскольку между старым и новым индексами нет перекрытия между датами и временем, переиндексация выводит все NaN:

# The following outputs all NaN as no date times match old to new index
series.reindex(desired_index)

Я не хочу заполнять ближайшие значения во время reindex, поскольку это приведет к потере точности, поэтому япридумал следующее;конкатенируйте переиндексированный ряд с оригиналом перед интерполяцией:

pandas.concat([series,series.reindex(desired_index)]).sort_index().interpolate(method="linear")

Это кажется очень неэффективным, конкатенируя и затем сортируя две серии.Есть ли лучший способ?

1 Ответ

0 голосов
/ 08 октября 2018

Единственный (простой) способ сделать это - использовать resample для повышения разрешения до вашего временного разрешения (скажем, 1 секунды), а затем переиндексировать.

Получить пример DataFrame:

import numpy as np
import pandas as pd

np.random.seed(2)

df = (pd.DataFrame()
 .assign(SampleTime=pd.date_range(start='2018-10-01', end='2018-10-08', freq='30T')
                    + pd.to_timedelta(np.random.randint(-5, 5, size=337), unit='s'),
         Value=np.random.randn(337)
         )
 .set_index(['SampleTime'])
)

Давайте посмотрим, как выглядят данные:

df.head()

                        Value
SampleTime
2018-10-01 00:00:03     0.033171
2018-10-01 00:30:03     0.481966
2018-10-01 01:00:01     -0.495496

Получите нужный индекс:

desired_index = pd.date_range('2018-10-01', periods=10, freq='30T')

Теперь переиндексируем данные с помощью объединениятребуемые и существующие индексы, интерполируйте на основе времени и снова переиндексируйте, используя только нужный индекс:

(df
 .reindex(df.index.union(desired_index))
 .interpolate(method='time')
 .reindex(desired_index)
)

                        Value
2018-10-01 00:00:00     NaN
2018-10-01 00:30:00     0.481218
2018-10-01 01:00:00     -0.494952
2018-10-01 01:30:00     -0.103270

Как вы можете видеть, у вас все еще есть проблема с первой отметкой времени, поскольку она выходит за пределы диапазонаисходный указатель;Есть несколько способов справиться с этим (pad, например).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...