【问题标题】:Extracting specific rows based on increasing or decreasing values in Pandas dataframe根据 Pandas 数据框中增加或减少的值提取特定行
【发布时间】:2022-11-16 20:00:44
【问题描述】:

我有一个包含两列和一个日期时间索引的大型数据框。绘制它的一部分时,它看起来像这样:

基本上,根据 SOC 列,数据可以上升(充电)或下降(放电)(有时在这些循环中保持不变)。

数据框如下所示:

                      SoC  Power
2021-09-25 16:40:00  0.76   2.18  
2021-09-25 16:40:10  0.76   2.14  
2021-09-25 16:40:20  0.77   2.18  
2021-09-25 16:40:30  0.76   1.14
2021-09-25 16:40:30  0.75   1.14
2021-09-25 16:40:30  0.75   1.14

我想提取第一个充电和放电周期。在此示例中,预期输出将是新的数据帧:

“收费”:

                      SoC  Power
2021-09-25 16:40:00  0.76   2.18  
2021-09-25 16:40:10  0.76   2.14  
2021-09-25 16:40:20  0.77   2.18 

“放电”

                      SoC  Power
2021-09-25 16:40:30  0.76   1.14
2021-09-25 16:40:30  0.75   1.14
2021-09-25 16:40:30  0.75   1.14

我最接近的提取充电会话的方法如下:

max = df_3['SoC'].diff() < 0
idx = max.idxmax()
df = df.loc[df.index[0]:idx]

但是,它仅在数据以充电会话开始时才起作用(因为它所做的只是在值开始减少时停止)。我想要一个解决方案,尽管有初始数据点,但仍能提供第一个充电周期数据点。

【问题讨论】:

  • 您应该提供数据的最小示例(以及预期的输出)
  • 按照this 创建一个最小的工作示例。
  • 你能分享你的预期输出吗?输出中的预期日期
  • 我认为寻找最大/最小值可能不是找到循环的正确方法。您应该检查范围,并确定一个高/低阈值(比如 95%/5%),然后使用它来确定充电周期的开始/结束。
  • 您好,感谢 cmets,我刚刚编辑了帖子。希望现在清楚了:)

标签: python pandas dataframe


【解决方案1】:

确切的预期输出尚不清楚,但这里有一种在字典中拆分每个阶段(充电、放电)的方法(2 种状态:充电/放电,每个状态都有所有阶段的列表):

s = np.sign(df['SoC'].diff())
s2 = s.mask(s.eq(0)).ffill().bfill().map({1: 'charging', -1: 'discharging'})

from collections import defaultdict
out = defaultdict(list)
for (status,_), d in s2.groupby([s2, s2.ne(s2.shift()).cumsum()]):
    out[status].append(d)
    
dict(out)

输出:

{'charging': [2021-09-25 16:40:00    charging
  2021-09-25 16:40:10    charging
  2021-09-25 16:40:20    charging
  Name: SoC, dtype: object],
 'discharging': [2021-09-25 16:40:30    discharging
  2021-09-25 16:40:30    discharging
  2021-09-25 16:40:30    discharging
  Name: SoC, dtype: object]}

对于单个项目:

out['charging'][0]

输出:

2021-09-25 16:40:00    charging
2021-09-25 16:40:10    charging
2021-09-25 16:40:20    charging
Name: SoC, dtype: object

作为数据框:

s = np.sign(df['SoC'].diff())
df['status'] = (s.mask(s.eq(0)).ffill().bfill()
                 .map({1: 'charging', -1: 'discharging'})
                )
df['phase']  = s2.ne(s2.shift()).cumsum()

输出:

                      SoC  Power       status  phase
2021-09-25 16:40:00  0.76   2.18     charging      1
2021-09-25 16:40:10  0.76   2.14     charging      1
2021-09-25 16:40:20  0.77   2.18     charging      1
2021-09-25 16:40:30  0.76   1.14  discharging      2
2021-09-25 16:40:30  0.75   1.14  discharging      2
2021-09-25 16:40:30  0.75   1.14  discharging      2

【讨论】:

    【解决方案2】:

    我不知道数据是怎样的,但我认为创建一个遍历数据的窗口是个好主意,哪个 pandas 有它的功能。

    我解释: 窗口开始时很小,它在数据中移动,并可能通过检查增加或减少的模式是否仍然存在来增加大小。如果模式发生变化,窗口将转换为原始大小并重复该过程直到结束。

    【讨论】:

    • 您的答案可以通过其他支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写出好的答案的信息in the help center
    【解决方案3】:

    如何获得多个充电和放电实例并记下每个实例的最小 soc 和最大 soc?

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多