为不规则间隔的数据查找最接近特定时间的每日观测值

Posted

技术标签:

【中文标题】为不规则间隔的数据查找最接近特定时间的每日观测值【英文标题】:Find daily observation closest to specific time for irregularly spaced data 【发布时间】:2017-07-01 16:24:18 【问题描述】:

我有一个类似的 python 数据框

Out[110]:
Time
2014-09-19 21:59:14    55.975
2014-09-19 21:56:08    55.925
2014-09-19 21:53:05    55.950
2014-09-19 21:50:29    55.950
2014-09-19 21:50:03    55.925
2014-09-19 21:47:00    56.150
2014-09-19 21:53:57    56.225
2014-09-19 21:40:51    56.225
2014-09-19 21:37:50    56.300
2014-09-19 21:34:46    56.300
2014-09-19 21:31:41    56.350
2014-09-19 21:30:08    56.500
2014-09-19 21:28:39    56.375
2014-09-19 21:25:34    56.350
2014-09-19 21:22:32    56.400
2014-09-19 21:19:27    56.325
2014-09-19 21:16:25    56.325
2014-09-19 21:13:21    56.350
2014-09-19 21:10:18    56.425
2014-09-19 21:07:13    56.475
Name: Spread, dtype: float64

它会持续很长时间(几个月到几年),因此每天都有很多观察。我想要做的是,我每天都想检索最接近特定时间的时间序列观察,比如 16:00。

到目前为止我的方法是

eodsearch = pd.DataFrame(df['Date'] + datetime.timedelta(hours=16))

eod = df.iloc[df.index.get_loc(eodsearch['Date'] ,method='nearest')]

目前给我一个错误

"Cannot convert input [Time Date, dtype: datetime64[ns]] of type <class 'pandas.core.series.Series'> to Timestamp 

此外,我看到 get_loc 也接受了容差作为输入,所以如果我可以将容差设置为 30 分钟,那就太好了。

关于我的代码为何失败或如何修复它的任何建议?

【问题讨论】:

请不要将数据作为图片发布。我已经手动输入了您的数据并替换了图像并将您的代码格式化为代码。请参阅Markdown help,了解如何在您的问题和答案中格式化代码。 【参考方案1】:

准备数据:

from pandas.tseries.offsets import Hour

df.sort_index(inplace=True)  # Sort indices of original DF if not in sorted order
# Create a lookup dataframe whose index is offsetted by 16 hours
d = pd.DataFrame(dict(Time=pd.unique(df.index.date) + Hour(16)))

(i):使用支持双向观察观察的reindex(双向兼容)

# Find values in original within +/- 30 minute interval of lookup 
df.reindex(d['Time'], method='nearest', tolerance=pd.Timedelta('30Min'))


(ii) :在识别原始DF中的唯一日期后使用merge_asof:(向后兼容)

# Find values in original within 30 minute interval of lookup (backwards)
pd.merge_asof(d, df.reset_index(), on='Time', tolerance=pd.Timedelta('30Min'))


(iii):通过查询和重新索引获取从+/- 30 分钟带宽间隔的日期:

Index.get_loc 对输入的单个标签进行操作,因此不能将整个系列对象直接传递给它。

相反,DatetimeIndex.indexer_between_time 会更适合此目的,它会按天提供位于指定索引的 start_timeend_time 内的所有行。 (两个端点都包括在内)


# Tolerance of +/- 30 minutes from 16:00:00
df.iloc[df.index.indexer_between_time("15:30:00", "16:30:00")]

用于得出结果的数据:

idx = pd.date_range('1/1/2017', periods=200, freq='20T', name='Time')
np.random.seed(42)
df = pd.DataFrame(dict(observation=np.random.uniform(50,60,200)), idx)
# Shuffle indices
df = df.sample(frac=1., random_state=42)

信息:

df.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 200 entries, 2017-01-02 07:40:00 to 2017-01-02 10:00:00
Data columns (total 1 columns):
observation    200 non-null float64
dtypes: float64(1)
memory usage: 3.1 KB

【讨论】:

在检查输出后,merge_asof 似乎只查看指定时间点之前的值,所以不是 +/- 而是只有 - ? From (pandas.pydata.org/pandas-docs/stable/generated/…) 我发现“对于左侧DataFrame中的每一行,我们选择右侧DataFrame中'on'键小于或等于左侧键的最后一行。” 然而情况似乎如此。目前似乎正在关注direction='backward'。从v 0.20.0 开始,您可以提供direction='nearest' 以及设置的容差区间,以实现+/- 的匹配带宽。顺便说一句,观察力不错。 添加了一种替代方法,希望能提供+/- 的匹配范围。请检查。 我花了一些时间(真的是上周才开始用 Python 编码)但是现在它似乎按预期工作了,非常感谢!

以上是关于为不规则间隔的数据查找最接近特定时间的每日观测值的主要内容,如果未能解决你的问题,请参考以下文章

数据挖掘的聚类算法和优势

在 std::map 中查找最接近或准确的键

每日一题 | day12( 二进制插入 | 查找组成一个偶数最接近的两个素数)

sas如何计算相邻观测的差值

Java:查找最接近特定负数的数组列表中的值

排序区间查询