Python Pandas - 查找具有最大聚合值的连续组

时间:2017-02-17 22:05:28

标签: python python-2.7 pandas numpy grouping

我有一个包含日期时间和整数的数据框

import numpy as np
import pandas as pd

df = pd.DataFrame()
df['dt'] = pd.date_range("2017-01-01 12:00", "2017-01-01 12:30", freq="1min")
df['val'] = np.random.choice(xrange(1, 100), df.shape[0])

给我

                    dt  val
0  2017-01-01 12:00:00   33
1  2017-01-01 12:01:00   42
2  2017-01-01 12:02:00   44
3  2017-01-01 12:03:00    6
4  2017-01-01 12:04:00   70
5  2017-01-01 12:05:00   94*
6  2017-01-01 12:06:00   42*
7  2017-01-01 12:07:00   97*
8  2017-01-01 12:08:00   12
9  2017-01-01 12:09:00   11
10 2017-01-01 12:10:00   66
11 2017-01-01 12:11:00   71
12 2017-01-01 12:12:00   25
13 2017-01-01 12:13:00   23
14 2017-01-01 12:14:00   39
15 2017-01-01 12:15:00   25

如何找到N分钟连续 dt的哪一组给我最大总和val

在这种情况下,如果N=3,则结果应为:

                    dt  val
5  2017-01-01 12:05:00   94
6  2017-01-01 12:06:00   42
7  2017-01-01 12:07:00   97

(上面标有星星)

3 个答案:

答案 0 :(得分:6)

您可以使用rolling/sumnp.nanargmax查找与第一次出现的最大值相关联的索引:

render :show, template: "api/items/show.json"

打印

import numpy as np
import pandas as pd

df = pd.DataFrame({'dt': ['2017-01-01 12:00:00', '2017-01-01 12:01:00', '2017-01-01 12:02:00', '2017-01-01 12:03:00', '2017-01-01 12:04:00', '2017-01-01 12:05:00', '2017-01-01 12:06:00', '2017-01-01 12:07:00', '2017-01-01 12:08:00', '2017-01-01 12:09:00', '2017-01-01 12:10:00', '2017-01-01 12:11:00', '2017-01-01 12:12:00', '2017-01-01 12:13:00', '2017-01-01 12:14:00', '2017-01-01 12:15:00'], 'val': [33, 42, 44, 6, 70, 94, 42, 97, 12, 11, 66, 71, 25, 23, 39, 25]})
df.index = df.index*10

N = 3
idx = df['val'].rolling(window=N).sum()
i = np.nanargmax(idx) + 1
print(df.iloc[i-N : i])

iloc uses ordinal indexing dt val 50 2017-01-01 12:05:00 94 60 2017-01-01 12:06:00 42 70 2017-01-01 12:07:00 97 使用基于标签的索引。只要 loci-N都是有效索引,i会占用一个窗口 (sub-DataFrame)长度为df.iloc[i-N : i]。相比之下,N只会抓住一个 如果索引使用连续的整数,则长度为df.loc[i-N, i]的窗口。上面的例子 显示自N以来df.loc无效的DataFrame 非连续的整数值。

答案 1 :(得分:6)

您可以使用np.convolve来获取正确的起始索引并从那里开始。

def cons_max(df, N):
    max_loc = np.convolve(df.val, np.ones(N, dtype=int), mode='valid').argmax()
    return df.loc[max_loc:max_loc+N-1]

<强>演示

>>> cons_max(df, 3)
                   dt  val
5 2017-01-01 12:05:00   94
6 2017-01-01 12:06:00   42
7 2017-01-01 12:07:00   97

>>> cons_max(df, 5)
                   dt  val
4 2017-01-01 12:04:00   70
5 2017-01-01 12:05:00   94
6 2017-01-01 12:06:00   42
7 2017-01-01 12:07:00   97
8 2017-01-01 12:08:00   12

这是有效的&#34;滑动&#34;我们的输入中的内核(一组数组),并在我们的窗口大小N中多次累加元素。

答案 2 :(得分:1)

对于简单的单个值,您可以使用以下内容:

df['total'] = df.val + df.val.shift(-1) + df.val.shift(-2)
first = df.dropna().sort('total').index[-1]
df.iloc[first:first+3]

不确定如何概括这个......对于大多数的熊猫来说,可能有一种更简单的方法,但这确实有效。

编辑:再做一点工作后,看起来滚动就是你想要的:

last = df.val.rolling(3).sum().dropna().sort_values().index[-1]

这有点不同,因为你在这里得到的索引是 end ,所以在你做完上面的事后你想做

df.iloc[last-2:last+1]

我认为可以推广。