【问题标题】:Python Pandas: Create Column That Acts As A Conditional Running VariablePython Pandas:创建作为条件运行变量的列
【发布时间】:2018-10-13 02:24:47
【问题描述】:

我正在尝试创建一个新的数据框列,该列充当运行变量,在某些条件下重置为零或“通过”。下面是我想要完成的一个简化示例。假设我正在尝试戒掉咖啡,并且我正在跟踪我连续几天不喝咖啡。在我忘记记录是否喝咖啡的日子里,我输入了“忘记”,并且我的计数不会受到影响。

以下是我目前的实现方式,尽管我怀疑有一种更有效的方法。

提前致谢!

import pandas as pd

Day = [1,2,3,4,5,6,7,8,9,10,11]  
DrankCoffee = ['no','no','forgot','yes','no','no','no','no','no','yes','no']

df = pd.DataFrame(list(zip(Day,DrankCoffee)), columns=['Day','DrankCoffee'])

df['Streak'] = 0  

s = 0

for (index,row) in df.iterrows():
   if row['DrankCoffee'] == 'no':
      s += 1
   if row['DrankCoffee'] == 'yes':
      s = 0
   else:
      pass

   df.loc[index,'Streak'] = s

【问题讨论】:

  • 您能否详细说明问题的结构?因为您似乎可以使用 iloc 并跟踪您的连续列中的最后一个 0。让我们称之为zero_streak。如果下一个条目是yes,那么只需将zero_streak 索引中的+1 添加到当前索引。如果no 则将新行设置为 0 并将您的zero_streak 更新为新索引

标签: python python-3.x pandas dataframe conditional-statements


【解决方案1】:

用途:

df['Streak'] = df.assign(streak=df['DrankCoffee'].eq('no'))\
                 .groupby(df['DrankCoffee'].eq('yes').cumsum())['streak'].cumsum().astype(int)

输出:

    Day DrankCoffee  Streak
0     1          no       1
1     2          no       2
2     3      forgot       2
3     4         yes       0
4     5          no       1
5     6          no       2
6     7          no       3
7     8          no       4
8     9          no       5
9    10         yes       0
10   11          no       1
  1. 首先,当 'no' 然后 True 时创建连续增量。
  2. 接下来,在“是”时使用 cumsum() 开始新的连胜。
  3. 最后,使用 cumsum 计算条纹中的条纹增量 cumsum()。

【讨论】:

    【解决方案2】:

    你可以使用groupby.transform

    对于每个streak,您正在寻找的是这样的:

    def my_func(group):
        return (group == 'no').cumsum()
    

    您可以通过简单的比较和cumsum来划分不同的条纹

    streak = (df['DrankCoffee'] == 'yes').cumsum()
    
    0     0
    1     0
    2     0
    3     1
    4     1
    5     1
    6     1
    7     1
    8     1
    9     2
    10    2
    

    然后应用变换

    df['Streak'] = df.groupby(streak)['DrankCoffee'].transform(my_func)
    

    【讨论】:

    • 谢谢!!所有的反应都很好,但我认为这个是我最容易理解的一步一步的过程。
    【解决方案3】:

    您需要首先将您的 DrankCoffee 映射到 [0,1](根据我的理解 yesforgot 应该是 0 而 no 是 1),然后我们只需执行 groupby cumsum 来创建组键,当有yes时,我们开始新一轮计算那些事件

    df.DrankCoffee.replace({'no':1,'forgot':0,'yes':0}).groupby((df.DrankCoffee=='yes').cumsum()).cumsum()
    Out[111]: 
    0     1
    1     2
    2     2
    3     0
    4     1
    5     2
    6     3
    7     4
    8     5
    9     0
    10    1
    Name: DrankCoffee, dtype: int64
    

    【讨论】:

    • 使用 == 'no' 将 DrankCoffee 映射到 0,1 会更容易
    猜你喜欢
    • 2015-02-09
    • 2019-06-05
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多