Я пытаюсь найти последовательные нулевые значения и застрял с этой проблемой на пару часов.
У меня есть DataFrame, например:
Day | ID | Values
-------------------
1 | aa | 0
1 | aa | 0
1 | aa | 0
1 | aa | 0
1 | aa | 2.5
1 | aa | 2.3
1 | aa | 0
1 | aa | 0
1 | aa | 0
2 | aa | 0
2 | aa | 0
2 | aa | 2.3
2 | aa | 0
1 | bb | 0
1 | bb | 0
1 | bb | 0
1 | bb | 0
1 | bb | 3.5
Я хочу найти последовательные значения нулей следующим образом:
Day | ID | Values | consec_zeros
--------------------------------------
1 | aa | 0 | 0
1 | aa | 0 | 1
1 | aa | 0 | 2
1 | aa | 0 | 3
1 | aa | 2.5 | 4 # --> there were 4 of consecutive 0s
1 | aa | 2.3 | 0 # 2.5 just destroy consecutive values
1 | aa | 0 | 0
1 | aa | 0 | 1
1 | aa | 0 | 2
2 | aa | 0 | 0 # no 0s before this of Day 2
2 | aa | 0 | 1
2 | aa | 2.3 | 2
2 | aa | 0 | 0
1 | bb | 0 | 0 # --> no 0s before this in ID 'bb'
1 | bb | 0 | 1
1 | bb | 0 | 2
1 | bb | 0 | 3
1 | bb | 3.5 | 4
То, что я пытался сделать, было:
g = df['Values'].ne(df['Values'].shift(1)).cumsum()
counts = df.groupby(['ID','Day',g])['Values'].transform('size')
df['consec_zeros'] = np.where(df['Values'].eq(0), counts, 0)
Поскольку я новичок в этом, пожалуйста, помогите и укажите мне, что я сделал неправильно.
заранее спасибо
@ascripter Я уже просматривал этот поток, но вывод последовательных zeos не в формате приращения, как мой желаемый вывод.
Вот основная проблема: добавить следующее значение счетчика по первым ненулевым значениям по GroupBy.cumcount
, но также использовать его для обнуления, в моем решении было добавлено 1
к счетчику для различения первого значения в счетчике:
g = df['Values'].ne(df['Values'].shift(1)).cumsum()
counts = df.groupby(['ID','Day',g])['Values'].cumcount() + 1
df['consec_zeros'] = np.where(df['Values'].eq(0), counts, 0)
#replace 0 to `NaN`s
a = df['consec_zeros'].mask(df['consec_zeros'].eq(0))
#add 1 to forward filling missing values by limit 1 per groups
df['consec_zeros'] = (np.where(a.isna(),
a.groupby([df['ID'],df['Day']]).ffill(limit=1) + 1,
df['consec_zeros']) - 1)
df['consec_zeros'] = df['consec_zeros'].fillna(0).astype(int)
print (df)
Day ID Values consec_zeros
0 1 aa 0.0 0
1 1 aa 0.0 1
2 1 aa 0.0 2
3 1 aa 0.0 3
4 1 aa 2.5 4
5 1 aa 2.3 0
6 1 aa 0.0 0
7 1 aa 0.0 1
8 1 aa 0.0 2
9 2 aa 0.0 0
10 2 aa 0.0 1
11 2 aa 2.3 2
12 2 aa 0.0 0
13 1 bb 0.0 0
14 1 bb 0.0 1
15 1 bb 0.0 2
16 1 bb 0.0 3
17 1 bb 3.5 4
Спасибо с хорошим объяснением. Это действительно работает. Большое спасибо!
@benji - я думаю, что нашел ошибку, необходимо заполнить форму по группам, поэтому отредактировал ответ.
Возможный дубликат GroupBy Pandas считает последовательные нули