在Python pandas DataFrame中对接近的日期时间进行分组

1 投票
1 回答
663 浏览
提问于 2025-05-01 10:28

我在这个问题上一直在苦苦挣扎,想知道有没有人能给我一些建议,告诉我该怎么处理。我有一个 pandas 的数据表,里面有很多列,其中有一列是日期时间格式。我想找到一种方法,把那些时间非常接近的记录“分组”在一起。比如说,如果一些交易在两秒内发生,我希望把它们放在一起,并给它们一个共同的标识,叫做“分组 ID”。

Transaction ID    Time    Grouped ID
    1          08:10:02       1
    2          08:10:03       1
    3          08:10:50
    4          08:10:55
    5          08:11:00       2
    6          08:11:01       2
    7          08:11:02       2
    8          08:11:03       3
    9          08:11:04       3
   10          08:15:00

需要注意的是,我并不想让这个时间窗口无限扩大。如果交易在很短的时间内继续发生,一旦过去了完整的两秒,下一笔交易就会开始一个新的时间窗口(就像交易 5 到 9 的情况)。另外,我最终会在毫秒级别进行这个分析(也就是说,把在 50 毫秒内的交易合并在一起),但为了简单起见,上面的例子我先用秒来说明。

非常感谢你们能提供的任何建议!

暂无标签

1 个回答

2

我建议的解决方案需要你用时间数据重新整理你的数据。你可以使用一个包含所需频率的日期时间列表,利用 searchsorted 来找到你索引中最接近的日期时间,然后用它来进行切片(就像在问题中提到的 python pandas 数据框按日期条件切片Python pandas,如何截断 DatetimeIndex 并仅在特定区间填充缺失数据)。

我使用的是 pandas 0.14.1 和 DataOffset 对象(http://pandas.pydata.org/pandas-docs/dev/timeseries.html?highlight=dateoffset)。我没有检查 datetime64,但我猜你可以调整代码。 DataOffset 可以精确到微秒级别。

使用以下代码,

import pandas as pd
import pandas.tseries.offsets as pto
import numpy as np

# Create some ome test data
d_size = 15
df = pd.DataFrame({"value": np.arange(d_size)}, index=pd.date_range("2014/11/03", periods=d_size, freq=pto.Milli()))

# Define periods to define groups (ticks)
ticks = pd.date_range("2014/11/03", periods=d_size/3, freq=5*pto.Milli())
# find nearest indexes matching the ticks
index_ticks = np.unique(df.index.searchsorted(ticks))

# make a dataframe with the group ids
dgroups = pa.DataFrame(index=df.index, columns=['Group id',])

# sets the group ids
for i, (mini, maxi) in enumerate(zip(index_ticks[:-1], index_ticks[1:])):
    dgroups.loc[mini:maxi] = i

# update original dataframe
df['Group id'] = dgroups['Group id']

我得到了这样的数据框:

                            value Group id
2014-11-03 00:00:00             0        0
2014-11-03 00:00:00.001000      1        0
2014-11-03 00:00:00.002000      2        0
2014-11-03 00:00:00.003000      3        0
2014-11-03 00:00:00.004000      4        0
2014-11-03 00:00:00.005000      5        1
2014-11-03 00:00:00.006000      6        1
2014-11-03 00:00:00.007000      7        1
2014-11-03 00:00:00.008000      8        1
2014-11-03 00:00:00.009000      9        1
2014-11-03 00:00:00.010000     10        2
2014-11-03 00:00:00.011000     11        2
2014-11-03 00:00:00.012000     12        2
2014-11-03 00:00:00.013000     13        2
2014-11-03 00:00:00.014000     14        2

撰写回答