Python Pandas: создать столбец, который действует как условная переменная - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь создать новый столбец данных, который действует как бегущая переменная, которая сбрасывается в ноль или «проходит» при определенных условиях. Ниже приведен упрощенный пример того, чего я хочу достичь. Допустим, я пытаюсь бросить пить кофе и отслеживаю количество дней подряд, которые я провел, не выпив ни одного. В те дни, когда я забывал отмечать, пил ли я кофе, я ставил «забыл», и на мое подсчет не влияют.

Ниже я рассказываю, как я сейчас это делаю, хотя я подозреваю, что есть гораздо более эффективный способ сделать это.

Заранее спасибо!

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.at[index,'Streak'] = s

enter image description here

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

вы можете использовать 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)
0 голосов
/ 03 мая 2018

Использование:

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. Сначала создайте приращение полосы, когда «нет», затем «Истина».
  2. Далее создайте полосу, когда «да», начните новую полосу, используя cumsum ().
  3. Наконец, используйте cumsum для подсчета приращения полос в cumsum ().
0 голосов
/ 03 мая 2018

Сначала вам нужно сопоставить DrankCoffee с [0,1] (исходя из моего понимания yes и forgot должно быть 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...