熊猫遍历行和条件计数

灰猫90

我正在尝试在名为Stage的新列中使用条件计数遍历pandas Dataframe中的行。对于每个名称,阶段应从1开始,如果行之间的名称相同,则在“健康”状态之后,应开始一个新阶段。如果存在,则“健康”事件将与之前的“病态”事件处于同一阶段。我之前已经在excel中完成了代码,但不确定如何在python中完成代码。

我现在所拥有的是:

日期 姓名 阶段
2020-01-02 玛丽 健康
2020-01-05 玛丽 生病的
2020-01-15 玛丽 生病的
2020-01-20 玛丽 健康
2020-02-03 玛丽 健康
2020-02-06 玛丽 生病的
2020-02-10 玛丽 生病的
2020-02-15 玛丽 健康
2020-01-02 鲍勃 健康
2020-01-05 鲍勃 健康
2020-01-15 鲍勃 健康
2020-01-20 鲍勃 生病的
2020-02-03 鲍勃 生病的
2020-02-06 鲍勃 生病的
2020-02-10 鲍勃 生病的
2020-02-15 鲍勃 健康

我想要的是:

日期 姓名 状态 阶段
2020-01-02 玛丽 健康 1个
2020-01-05 玛丽 生病的 2个
2020-01-15 玛丽 生病的 2个
2020-01-20 玛丽 健康 2个
2020-02-03 玛丽 健康 3
2020-02-06 玛丽 生病的 4
2020-02-10 玛丽 生病的 4
2020-02-15 玛丽 健康 4
2020-01-02 鲍勃 健康 1个
2020-01-05 鲍勃 健康 2个
2020-01-15 鲍勃 健康 3
2020-01-20 鲍勃 生病的 4
2020-02-03 鲍勃 生病的 4
2020-02-06 鲍勃 生病的 4
2020-02-10 鲍勃 生病的 4
2020-02-15 鲍勃 健康 4
保罗·H

您不需要显式循环。您需要以下内容:

  • group by the name column
  • apply to each group:
    • shift the Status column to look at the previous value
    • take cumulative sum of the following series:
      • if the previous value is null and current value is Healthy, we're at the first row so call it one
      • if the previous row is Healthy, call it one
      • otherwise, call it zero

from io import StringIO

import numpy
import pandas

df = pandas.read_csv(StringIO("""\
|Date|Name|Stage|
|2020-01-02|Mary|Healthy|
|2020-01-05|Mary|Sick|
|2020-01-15|Mary|Sick|
|2020-01-20|Mary|Healthy|
|2020-02-03|Mary|Healthy|
|2020-02-06|Mary|Sick|
|2020-02-10|Mary|Sick |
|2020-02-15|Mary|Healthy|
|2020-01-02|Bob|Healthy|
|2020-01-05|Bob|Healthy|
|2020-01-15|Bob|Healthy|
|2020-01-20|Bob|Sick|
|2020-02-03|Bob|Sick|
|2020-02-06|Bob|Sick|
|2020-02-10|Bob|Sick |
|2020-02-15|Bob|Healthy|
"""), sep='|').loc[:, ['Date', 'Name', 'Stage']]

output = (
    df.assign(Status=lambda df: df.groupby('Name')['Stage'].apply(lambda g: 
        numpy.bitwise_or(  #  returns 1 if either two conditions are met
            g.shift().eq('Healthy'),  # general case
            g.shift().isnull() & g.eq("Healthy") #  handles first row of a group
        ).cumsum()
    ))
)

print(output.to_string())

And I get:

          Date  Name    Stage  Status
0   2020-01-02  Mary  Healthy       1
1   2020-01-05  Mary     Sick       2
2   2020-01-15  Mary     Sick       2
3   2020-01-20  Mary  Healthy       2
4   2020-02-03  Mary  Healthy       3
5   2020-02-06  Mary     Sick       4
6   2020-02-10  Mary    Sick        4
7   2020-02-15  Mary  Healthy       4
8   2020-01-02   Bob  Healthy       1
9   2020-01-05   Bob  Healthy       2
10  2020-01-15   Bob  Healthy       3
11  2020-01-20   Bob     Sick       4
12  2020-02-03   Bob     Sick       4
13  2020-02-06   Bob     Sick       4
14  2020-02-10   Bob    Sick        4
15  2020-02-15   Bob  Healthy       4

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章