假设我希望使用线性插值将时间序列重新索引到预定义的索引,其中新旧索引之间不共享任何索引值。例如
# 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
,然后使用 interpolate
填充 NaN 值。但是,由于新旧索引之间的日期时间没有重叠,因此重新索引会输出所有 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")
这似乎非常低效,连接然后对两个系列进行排序。有更好的办法吗?
我能看到的唯一(简单)方法是使用 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
)。
我的方法
frequency = nyse_trading_dates.rename_axis([None]).index
df = prices.rename_axis([None]).reindex(frequency)
for d in prices.rename_axis([None]).index:
df.loc[d] = prices.loc[d]
df.interpolate(method='linear')
方法2
prices = data.loc[~data.index.duplicated(keep='last')]
#prices = data.reset_index()
idx1 = prices.index
idx1 = pd.to_datetime(idx1, errors='coerce')
merged = idx1.union(idx2)
s = prices.reindex(merged)
df = s.interpolate(method='linear').dropna(axis=0, how='any')
data=df
我用的是组合索引。第一步是声明所需的索引。 然后,将其与现有索引结合起来。 现在重新索引到组合索引并使用插值、ffill 或任何其他函数填充 NaN。 然后再次重新索引到新索引。
# Create a new time series with minute frequency
new_index = pd.date_range(temperature_data.index.min(), temperature_data.index.max(), freq='min')
#Create combined index for ffill or interpolation etc.
combined_index = new_index.union(temperature_data.index)
#Reindex to combined index
resampled_ts = temperature_data.reindex(combined_index)
# Apply interpolation to fill missing values
resampled_ts = resampled_ts.interpolate(method='linear')
# Resample the combined time series to minute frequency
resampled_ts = resampled_ts.reindex(new_index)