у меня вот такая дф
name class date value
Andy A 20220101 0
Andy A 20220103 1
Andy A 20220104 0
Bob Z 20221120 0
Bob Z 20221121 0
Bob Z 20221125 0
Bob Z 20221127 1
Столбец value
принимает значение только 0 или 1. Для каждой группы (определяемой двумя столбцами name
и class
) столбец date
является порядком в порядке возрастания. Я пытаюсь рассчитать для каждой группы соотношение: количество раз, когда значение столбца value
изменяется (0 -> 1 или 1 -> 0), деленное на количество дат с данными.
Для приведенного выше кадра данных группа (Энди, А) меняется 2 раза за 3 дня, поэтому соотношение составляет 2/3. Группа (Боб, Z) меняется 1 раз за 4 дня, поэтому соотношение 1/4=0,25.
Интересно, есть ли способ сделать это эффективно в Pandas?
можете ли вы поделиться кодом для построения ваших данных?
Это работает
# mark the changes in value
df['changes'] = df['value'].diff().ne(0).cumsum()
# count the number of changes and the number of values for each name
aggregated = df.groupby('name').agg({'changes':'nunique', 'value':'size'})
# by construction, we counted the original, so to count the "changes", we must subtract 1
aggregated['changes'] -= 1
# find the ratio
final = aggregated['changes'] / aggregated['value']
name
Andy 0.666667
Bob 0.250000
dtype: float64
Ты можешь попробовать
out = (df
.groupby(['name', 'class']).apply(lambda g: g['value'].shift().bfill().ne(g['value']).sum()/g['date'].nunique())
.round(2)
.to_frame('ratio')
.reset_index())
print(out)
name class ratio
0 Andy A 0.67
1 Bob Z 0.25
что ты уже испробовал?