pandas 如果值连续减少/增加3天以上,则根据此情况创建组Python

des4xlb0  于 2023-03-21  发布在  Python
关注(0)|答案(1)|浏览(107)

我有一个dataframe,我想创建新的分组,每次值已减少或增加了3个相应的天。
数据框:

df = pd.DataFrame({'date': ['2022-09-01', '2022-09-02', ...], 'value': [10, 8, ...]})

示例:
Dataframe :
| 日期|价值|
| - ------|- ------|
| 2022年9月1日|十个|
| 2022年9月2日|八个|
| 2022年9月3日|九|
| 2022年9月4日|八个|
| 2022年9月5日|六个|
| 2022年9月6日|第二章|
| 2022年9月7日|四个|
| 2022年9月8日|五个|
| 2022年9月9日|六个|
| 2022年9月10日|五个|
| 2022年9月11日|八个|
| 2022年9月12日|九|
| 2022年9月13日|十个|
| 2022年9月14日|十一|
| 2022年9月15日|第二章|
预期输出:
| 日期|价值|群|
| - ------|- ------|- ------|
| 2022年9月1日|十个|1个|
| 2022年9月2日|八个|1个|
| 2022年9月3日|九|1个|
| 2022年9月4日|八个|1个|
| 2022年9月5日|六个|1个|
| 2022年9月6日|第二章|1个|
| 2022年9月7日|四个|第二章|
| 2022年9月8日|五个|第二章|
| 2022年9月9日|六个|第二章|
| 2022年9月10日|五个|三个|
| 2022年9月11日|八个|三个|
| 2022年9月12日|九|三个|
| 2022年9月13日|十个|三个|
| 2022年9月14日|十一|四个|
| 2022年9月15日|第二章|四个|
我试图创建另一列,其中显示1为增加和-1为减少。然后我的计划是总和值,直到总和大于3或小于3,并以某种方式创建一个分组的基础上。然而,我没有走得更远....

l = []
for i in range(len(df['value'])-1):
    if (df['value'][i + 1]) > (df['value'][i]):
        l.append(1)
    elif (df['value'][i + 1]) < (df['value'][i]):
        l.append(-1)
    else:
        l.append(0)

我的主要目标是能够创建线性斜坡(类似于图中的红线),这些斜坡具有相同的坡度,直到三天出现,之后坡度发生变化。

omqzjyyz

omqzjyyz1#

一般来说,你要避免迭代数据框的行。相反,尽量总是使用内置函数。在这种情况下,首先使用diff计算差异。

df['delta'] = -df.value.diff(-1)

然后可以使用np.sign来计算差的值

df['delta_sign'] = np.sign(df.delta)

由于问题要求查看连续3天,因此需要查看2个连续差异,我们需要创建一个滚动窗口并对其求和

df['three_set_behaviour']=df.delta_sign.rolling(2).sum().shift(-1)

注意shift(-1)是必需的,因为pandas总是将窗口上的聚合结果放在窗口的右边,而我们希望它在左边。
现在,由于只有三个连续的增加/减少对群体行为有影响,我们需要首先消除所有其他条目

df.loc[abs(df.three_set_behaviour) != 2,'three_set_behaviour'] = np.nan

然后用前三个分组所指示的行为来填充它们

df.three_set_behaviour = df.three_set_behaviour.ffill()

请注意,您的问题留下了未定义的值应该发生什么,直到前三个分组。一个选项是将时间序列中第一个分组的行为强加给它们

df.three_set_behaviour = df.three_set_behaviour.bfill()

由于three_set_behaviour现在包含所有条目的方向,因此可以使用以下公式计算方向和组的变化

df['group_change'] = df.three_set_behaviour != df.three_set_behaviour.shift(1)

可以对其进行累积和以得到当前组。

df['group'] = df.group_change.cumsum()

这导致df包含
| 价值|三角洲|δ符号|三集行为|组_更改|群|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 十个|-2.0|-1.0|-2.0|真的|1个|
| 八个|1.0分|1.0分|-2.0|假|1个|
| 九|-1.0|-1.0|-2.0|假|1个|
| 八个|-2.0|-1.0|-2.0|假|1个|
| 六个|负4.0|-1.0|-2.0|假|1个|
| 第二章|2.0版|1.0分|2.0版|真的|第二章|
| 四个|1.0分|1.0分|2.0版|假|第二章|
| 五个|1.0分|1.0分|2.0版|假|第二章|
| 六个|-1.0|-1.0|2.0版|假|第二章|
| 五个|3.0版|1.0分|2.0版|假|第二章|
| 八个|1.0分|1.0分|2.0版|假|第二章|
| 九|1.0分|1.0分|2.0版|假|第二章|
| 十个|-5.0|-1.0|-2.0|真的|三个|
| 五个|-3.0|-1.0|-2.0|假|三个|
| 第二章|楠|楠|-2.0|假|三个|
请注意,我已经擅自更改了示例中倒数第二个值,使其也显示3个fallin值。

相关问题