查找许多类别的最近时间索引

时间:2018-01-02 00:13:06

标签: python pandas time-series

我正在尝试为多个独立类别(example in more detail in the gist)获取最接近查询时间戳的数据点:

dt = pd.to_datetime(dt)
df_output = list()
for category in df.category.unique():
    df_temp = df[df.category == category]
    i = df_temp.index.get_loc(dt, method='nearest')
    latest = df_temp.iloc[i]
    df_output.append(latest)

pd.DataFrame(df_output)

这种方法的问题在于它非常缓慢(显然感觉非常生硬)。分析表明瓶颈是iloc,这似乎很奇怪。

什么是更快/更正确的方法呢?有没有办法一次性获得所有类别的结果? (我在考虑一些groupby魔法)

pandas是否有能力这样做,还是应该切换到其他时间序列存储方法?

2 个答案:

答案 0 :(得分:1)

Pandas是为时间序列数据而制作的,所以这是它的面包和黄油。试试这个表现:

dt = '2017-12-23 01:49:13'
df["timedelta"] = abs(df.index - pd.Timestamp(dt))
df.loc[df.groupby(by="category")["timedelta"].idxmin()].drop("timedelta", axis=1)

这是创建一个名为timedelta的新列,以pandas.Timedelta类命名,然后使用groupby组合所有类别,找到每个类别中最小的timedelta并将其索引返回{{1} }。最后我放弃了专栏。

答案 1 :(得分:1)

您可以使用groupby执行此操作,但仍需要使用iloc。这是一个解决方案:

dt = pd.to_datetime('2017-12-23 01:50:30')

def find(df):
    return pd.DataFrame(df.iloc[df.index.get_loc(dt, method='nearest')]).T

new_df = df.groupby('category').apply(find)
new_df


                                        category    value
category            
A           2017-12-23 01:50:21.687     A           1
B           2017-12-23 01:50:21.661     B           3

如果您不想要指示该类别的多索引,您可以像这样删除它:

new_df.index = new_df.index.droplevel()
new_df

                            category    value

2017-12-23 01:50:21.687     A           1
2017-12-23 01:50:21.661     B           3