Pandas 带重叠的滚动函数

Pandas rolling function with overlap

我想将一个函数应用于一个 pandas 数据框列,该列执行以下任务:

我目前使用的功能如下:

代码

import pandas as pd

d = {'Cycle':[100,100,100,100,101,101,101,102,102,102,102,102,102,103,103,103,100,100,100,100,101,101,101,101]}
df = pd.DataFrame(data=d)

df.loc[:,'counter'] = df['Cycle'].to_numpy()
df.loc[:,'counter'] = df['counter'].rolling(2).apply(lambda x: x[0] if (x[0] == x[1]) else x[0]+1, raw=True)

print(df)

输出

    Cycle  counter
0     100      NaN
1     100    100.0
2     100    100.0
3     100    100.0
4     101    101.0
5     101    101.0
6     101    101.0
7     102    102.0
8     102    102.0
9     102    102.0
10    102    102.0
11    102    102.0
12    102    102.0
13    103    103.0
14    103    103.0
15    103    103.0
16    100    104.0
17    100    100.0
18    100    100.0
19    100    100.0
20    101    101.0
21    101    101.0
22    101    101.0
23    101    101.0

我的目标是获得与此类似的数据框:

    Cycle  counter
0     100      NaN
1     100    100.0
2     100    100.0
3     100    100.0
4     101    101.0
5     101    101.0
6     101    101.0
7     102    102.0
8     102    102.0
9     102    102.0
10    102    102.0
11    102    102.0
12    102    102.0
13    103    103.0
14    103    103.0
15    103    103.0
16    100    104.0
17    100    104.0
18    100    104.0
19    100    104.0
20    101    105.0
21    101    105.0
22    101    105.0
23    101    105.0

此致,

马特奥

我们可以使用 shiftne(与 != 相同)来检查 Cycle 列更改的位置。

然后我们用cumsum做一个计数器,每次Cycle变化时都会变化。

我们将 Cycle 的第一个值添加到计数器 -1,让它从 100:

开始
groups = df['Cycle'].ne(df['Cycle'].shift()).cumsum()
df['counter'] = groups + df['Cycle'].iat[0] - 1

    Cycle  counter
0     100      100
1     100      100
2     100      100
3     100      100
4     101      101
5     101      101
6     101      101
7     102      102
8     102      102
9     102      102
10    102      102
11    102      102
12    102      102
13    103      103
14    103      103
15    103      103
16    100      104
17    100      104
18    100      104
19    100      104
20    101      105
21    101      105
22    101      105
23    101      105

详细信息:groups 为我们提供了一个从 1:

开始的计数器
print(groups)

0     1
1     1
2     1
3     1
4     2
5     2
6     2
7     3
8     3
9     3
10    3
11    3
12    3
13    4
14    4
15    4
16    5
17    5
18    5
19    5
20    6
21    6
22    6
23    6
Name: Cycle, dtype: int64

另一种方法是使用 .diff() 识别循环列中值发生变化的点。然后在这些点从原始初始循环值增加并合并到原始数据帧向前填充新值。

df2 = df[df['Cycle'].diff().apply(lambda x: x!=0)].reset_index()
df2['Target Count'] = df[df['Cycle'].diff().apply(lambda x: x!=0)].reset_index().reset_index().apply(lambda x: df.iloc[0,0] + x['level_0'], axis = 1)
df = df.merge(df2.drop('Cycle', axis = 1), right_on = 'index', left_index = True, how = 'left').ffill().set_index('index', drop = True)
def df.index.name
df

Cycle  Target Count
0     100         100.0
1     100         100.0
2     100         100.0
3     100         100.0
4     101         101.0
5     101         101.0
6     101         101.0
7     102         102.0
8     102         102.0
9     102         102.0
10    102         102.0
11    102         102.0
12    102         102.0
13    103         103.0
14    103         103.0
15    103         103.0
16    100         104.0
17    100         104.0
18    100         104.0
19    100         104.0
20    101         105.0
21    101         105.0
22    101         105.0
23    101         105.0