Как настроить счетчик значений для группы в Python - PullRequest
0 голосов
/ 11 ноября 2019

Я пытаюсь создать счетчик, который будет изменять значения только тогда, когда он отличается от предыдущей строки или идентификатора, который я группирую по изменениям

Допустим, у меня есть следующий фрейм данных:

ID Flag   New_Column
A   NaN     1
A   0       1
A   0       1
A   0       1
A   1       2
A   1       2
A   1       2
A   0       3
A   0       3
A   0       3
A   1       4
A   1       4
A   1       4
B   NaN     1
B   0       1

Я хочу создать New_Column, где каждый раз, когда меняются значения флага, я бы увеличивал New_Column на единицу, а если идентификатор менялся, он сбрасывался до единицы и начинался с

Вот что я пыталсяиспользовать np.select, но он не работает

df['New_Column'] = None
df['Flag_Lag'] = df.sort_values(by=['ID', 'Date_Time'], ascending=True).groupby(['ID'])['Flag'].shift(1)
df['ID_Lag'] = df.sort_values(by=['ID', 'Date_Time'], ascending=True).groupby(['ID'])['ID'].shift(1)


conditions = [((df['Flag'] != df['Flag_Lag']) & (df['ID'] == df['ID_Lag'])), 
              ((df['Flag'] == df['Flag_Lag']) & (df['ID'] == df['ID_Lag'])), 
              ((df['Flag_Lag'] == np.nan) & (df['New_Column'].shift(1) == 1)), 
              ((df['ID'] != df['ID_Lag']))
             ]

choices = [(df['New_Column'].shift(1) + 1), 
           (df['New_Column'].shift(1)), 
           (df['New_Column'].shift(1)), 
            1]

df['New_Column'] = np.select(conditions, choices, default=np.nan)

С этим кодом первое значение для New_Column равно 1, второе - NaN, а остальное - None

Кто-нибудь знаетлучший способ сделать это?

1 Ответ

1 голос
/ 11 ноября 2019

Если скорость не имеет значения, и вам нужен какой-то простой для чтения код, вы можете просто выполнить итерации по фрейму данных и запустить простую функцию для каждой строки.

def f(row):
    global previous_ID, previous_flag, previous_count

    if previous_ID == False: #let's start the count
        row['New_Column'] = 1

    elif previous_ID != row['ID']: #let's start the count over
        row['New_Column'] = 1

    elif previous_flag == row['Flag']: #same ID, same Flag
        row['New_Column'] = previous_count

    else: #same ID, different Flag
        row['New_Column'] = previous_count + 1


    previous_ID = row['ID']
    previous_flag = row['Flag']
    previous_count = row['New_Column']

Вы должны заполнить свой NaNзначения с 0, вероятно, или добавьте специальный случай в функцию для него.

Вы можете запустить функцию следующим образом:

previous_ID, previous_flag, previous_count = False, False, False
df['New_Columns'] = []

for i, row in df.iterrows():
    f(row)

И это все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...