Skip to main content
 首页 » 编程设计

python之如何使用 Pandas 按时间序列中的一个或多个维度分组

2025年05月04日15grandyang

我有这样的数据:

timestamp, country_code,  request_type,   latency 
2013-10-10-13:40:01,  1,    get_account,    134 
2013-10-10-13:40:63,  34,   get_account,    256 
2013-10-10-13:41:09,  230,  modify_account, 589 
2013-10-10-13:41:12,  230,  get_account,    43 
2013-10-10-13:53:12,  1,    modify_account, 1003 

其中时间戳为秒分辨率且不规则。

如何在 pandas 中表达如下查询:

  • 10 分钟内每个国家/地区代码的请求数?
  • 1 分钟解析度下 request_type 的 99% 百分位延迟?
  • 每 country_code 和 request_type 在 10 分钟内解决的请求数?

然后在同一张图上绘制所有组,随着时间的推移,每个组都作为自己的线。

更新:

根据 1 的建议,我有:

bycc = df.groupby('country_code').reason.resample('10T', how='count') 
bycc.plot() # BAD: uses (country_code, timestamp) on the x axis 
bycc[1].plot() # properly graphs the time-series for country_code=1 

但似乎无法找到简单的方法来将每个国家/地区代码绘制为单独的一行,并在 x 轴上使用适当的时间戳,在 y 轴上使用值。我认为有 2 个问题(1)每个国家/地区代码的时间戳都不相同,它们需要在相同的开始/结束处对齐,并且(2)需要从多索引 TimeSeries 对象中找到正确的 API/方法为多索引的每个第一个值绘制一条线的单个图。以我的方式工作......

更新 2

以下似乎可以做到这一点:

i = 0 
max = 3 
pylab.rcParams['figure.figsize'] = (20.0, 10.0) # get bigger graph 
for cc in bycc.index.levels[0]: 
    i = i + 1 
    if (i <= max): 
        cclabel = "cc=%d" % (cc) 
        bycc[cc].plot(legend=True, label=cclabel) 

只打印最大值,因为它变得嘈杂。 现在开始弄清楚如何更好地显示包含大量时间序列的图。

请您参考如下方法:

注意:pandas 无法解析日期时间字符串“2013-10-10-13:40:63”,因为每分钟多了 4 秒(dateutil无法解析;pandas 使用 dateutil 来解析日期)。为了便于说明,我已将其转换为“2013-10-10-13:40:59”。

1。在 10 分钟分辨率下每个 country_code 的请求数:

In [83]: df 
Out[83]: 
                     country_code    request_type  latency 
timestamp 
2013-10-10 13:40:01             1     get_account      134 
2013-10-10 13:40:59            34     get_account      256 
2013-10-10 13:41:09           230  modify_account      589 
2013-10-10 13:41:12           230     get_account       43 
2013-10-10 13:53:12             1  modify_account     1003 
 
In [100]: df.groupby('country_code').request_type.resample('10T', how='count') 
Out[100]: 
country_code  timestamp 
1             2013-10-10 13:40:00    1 
              2013-10-10 13:50:00    1 
34            2013-10-10 13:40:00    1 
230           2013-10-10 13:40:00    2 
dtype: int64 

2。 request_type 在 1 分钟分辨率下的 latency 的第 99 个百分位

这里也可以采用非常相似的方法:

In [107]: df.groupby('request_type').latency.resample('T', how=lambda x: x.quantile(0.99)) 
Out[107]: 
request_type    timestamp 
get_account     2013-10-10 13:40:00     254.78 
                2013-10-10 13:41:00      43.00 
modify_account  2013-10-10 13:41:00     589.00 
                2013-10-10 13:42:00        NaN 
                2013-10-10 13:43:00        NaN 
                2013-10-10 13:44:00        NaN 
                2013-10-10 13:45:00        NaN 
                2013-10-10 13:46:00        NaN 
                2013-10-10 13:47:00        NaN 
                2013-10-10 13:48:00        NaN 
                2013-10-10 13:49:00        NaN 
                2013-10-10 13:50:00        NaN 
                2013-10-10 13:51:00        NaN 
                2013-10-10 13:52:00        NaN 
                2013-10-10 13:53:00    1003.00 
dtype: float64 

3。每个 country_code 和 request_type 在 10 分钟分辨率下的请求数

这与 #1 基本相同,只是您要在对 DataFrame.groupby 的调用中添加一个额外的组:

In [108]: df.groupby(['country_code', 'request_type']).request_type.resample('10T', how='count') 
Out[108]: 
country_code  request_type    timestamp 
1             get_account     2013-10-10 13:40:00    1 
              modify_account  2013-10-10 13:50:00    1 
34            get_account     2013-10-10 13:40:00    1 
230           get_account     2013-10-10 13:40:00    1 
              modify_account  2013-10-10 13:40:00    1 
dtype: int64 

就情节而言,您的要求尚不清楚,请详细说明。