Pandas - 找到大小为n的行块,其中最高值恰好在中间而不使用循环

时间:2017-10-24 12:32:41

标签: python pandas dataframe indexing

在pandas数据帧中是否有办法找到大小为n的所有行块,其中最高值恰好在中间?我需要的是创建一个额外的列,其中只有每个这样的块的中间最大值的值。 以下是用于循环和块大小5的示例:

import pandas as pd

df = pd.DataFrame([1, 2, 3, 2, 1, 2, 1, 4, 3, 2, 1, 5, 2, 2, 5],
              columns = ['number'])
for i in range(2, len(df) - 2):
    if (df.loc[i, 'number'] > df.loc[i - 1, 'number'] and\
        df.loc[i, 'number'] > df.loc[i - 2, 'number'] and\
        df.loc[i, 'number'] > df.loc[i + 1, 'number'] and\
        df.loc[i, 'number'] > df.loc[i + 2, 'number']):
        df.loc[i, 'high'] = df.loc[i, 'number']

输出:

    number  high
0   1   None
1   2   None
2   3   3
3   2   None
4   1   None
5   2   None
6   1   None
7   4   4
8   3   None
9   2   None
10  1   None
11  5   5
12  2   None
13  2   None
14  5   None

2 个答案:

答案 0 :(得分:1)

您可以将pd.DataFrame.rolling与参数center=True一起使用。取最大值,并将其与目标进行比较。

def highest_in(s, n):
    test = s.rolling(window=n, center=True).max() == s
    return s.where(test, None)

df['high'] = highest_in(df.number, n=5)
print(df)
    # number  high
# 0        1  None
# 1        2  None
# 2        3     3
# 3        2  None
# 4        1  None
# 5        2  None
# 6        1  None
# 7        4     4
# 8        3  None
# 9        2  None
# 10       1  None
# 11       5     5
# 12       2  None
# 13       2  None
# 14       5  None

答案 1 :(得分:1)

我们也可以使用scipy中的argrelextrema按顺序获取局部最大值。这里的顺序是2来考虑上面的2个数字和下面的2个数字。通过考虑块大小为5的值。

from scipy.signal import argrelextrema
maxInd = argrelextrema(df.number.values, np.greater, order=2)

df['new'] = df.iloc[maxInd]['high']

输出:

   number  new
0        1  NaN
1        2  NaN
2        3  3.0
3        2  NaN
4        1  NaN
5        2  NaN
6        1  NaN
7        4  4.0
8        3  NaN
9        2  NaN
10       1  NaN
11       5  5.0
12       2  NaN
13       2  NaN
14       5  NaN