我正在尝试为多个独立类别(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
是否有能力这样做,还是应该切换到其他时间序列存储方法?
答案 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