如何有效地计算熊猫数据框中的运行最大值?

时间:2020-02-13 08:46:30

标签: python pandas dataframe

使用Pandas 1.0,我试图编写一个有效的程序来计算我的数据集中给定项目的每次观察的运行最大值(每个项目由相同的ID标识)。由于我正在使用iterrows()并通过索引设置每个高水位线,因此我的程序以极慢的速度完成该工作。数据集非常大,这不是可行的解决方案。

import pandas as pd
import sys

data = [[1, 10],
        [1, 15],
        [1, 10],
        [1, 0],
        [1, 5],
        [1, 20],
        [1, 0],
        [1, 10],
        [2, 5],
        [2, 15],
        [2, 10],
        [2, 20],
        [2, 25],
        [2, 20],
        [2, 30],
        [2, 10]]

df = pd.DataFrame(data, columns=['id', 'val'])
high_water_mark = -sys.maxsize
previous_row = None

for index, row in df.iterrows():

    current_val = row['val']

    if index == 0:
        df.loc[index, 'running_maximum'] = current_val
        high_water_mark = current_val
        previous_row = row
        continue

    if row['id'] == previous_row['id'].item():

        if current_val > high_water_mark:
            df.loc[index, 'running_maximum'] = current_val
            high_water_mark = current_val
        else:
            df.loc[index, 'running_maximum'] = high_water_mark

    else:
        df.loc[index, 'running_maximum'] = current_val
        high_water_mark = current_val

    previous_row = row

print(df)

输出:

    id  val  running_maximum
0    1   10             10.0
1    1   15             15.0
2    1   10             15.0
3    1    0             15.0
4    1    5             15.0
5    1   20             20.0
6    1    0             20.0
7    1   10             20.0
8    2    5              5.0
9    2   15             15.0
10   2   10             15.0
11   2   20             20.0
12   2   25             25.0
13   2   20             25.0
14   2   30             30.0
15   2   10             30.0

关于如何加快此过程的任何建议?

1 个答案:

答案 0 :(得分:7)

您有GroupBy.cummax可以做到:

df['running_maximum'] = df.groupby('id').val.cummax()

print(df)

    id  val  running_maximum
0    1   10               10
1    1   15               15
2    1   10               15
3    1    0               15
4    1    5               15
5    1   20               20
6    1    0               20
7    1   10               20
8    2    5                5
9    2   15               15
10   2   10               15
11   2   20               20
12   2   25               25
13   2   20               25
14   2   30               30
15   2   10               30

如果每个组具有相同数量的值(如本示例中所示),我们可以使用带有np.maximum.accumulate的NumPy加快速度:

df['running_maximum'] = np.maximum.accumulate(df.val.values.reshape(-1, 8), 1).ravel()