Как посчитать 1 в столбце и получить максимальное количество для каждой группы - PullRequest
2 голосов
/ 30 марта 2020

У меня есть фрейм данных со столбцами 'A' и 'flag'. я хочу применить групповую функцию и получить максимальное количество последовательных 1 в каждой группе

входные данные:

df=pd.DataFrame({'A':[1,1,1,1,1,1,2,2,2,2,2,2,2],'flag':[1,1,0,1,1,1,0,1,1,0,1,1,1]}) 

требуемый вывод

output= pd.DataFrame({'A':[1,1,1,1,1,1,2,2,2,2,2,2,2],'consective_count_max':[3,3,3,3,3,3,3,3,3,3,3,3,3]})  

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

IIU C, GroupBy.sum и Series.max с level=0. Мы можем использовать Series.map для создания серии с исходным индексом:

blocks=df['flag'].ne(df['flag'].shift()).cumsum()
df['consecutive_count_max'] = (df['A'].map(df.groupby(['A',blocks])['flag']
                                             .sum()
                                             .max(level=0)))
print(df)

    A  flag  consecutive_count_max
0   1     1                      3
1   1     1                      3
2   1     0                      3
3   1     1                      3
4   1     1                      3
5   1     1                      3
6   2     0                      3
7   2     1                      3
8   2     1                      3
9   2     0                      3
10  2     1                      3
11  2     1                      3
12  2     1                      3

обратите внимание, что при добавлении группы с flag == 0 никогда не получат сумму, превышающую группа с flag == 1, поэтому df['flag'].eq(1) НЕ требуется .

Если flag не равно 1 или 0, а затем необходимо проверить, например, df['flag'].eq('yes') .we могли бы использование:

mapper = pd.crosstab(df['flag'].ne(df['flag'].shift())
                               .cumsum()
                              .loc[df['flag'].eq(1)], df['A']).max()
df['consecituve_count_max'] = df['A'].map(mapper)
#print(df)

Деталь

print(df['flag'].ne(df['flag'].shift()).cumsum())

0     1
1     1
2     2
3     3
4     3
5     3
6     4
7     5
8     5
9     6
10    7
11    7
12    7
Name: flag, dtype: int64
1 голос
/ 30 марта 2020

Создать Series для последовательных значений по группам по Series.shift и Series.cumsum, фильтровать только 1 значения по маске m и затем считать значения по SeriesGroupBy.value_counts с max используется для отображения по исходному столбцу A по Series.map:

m = df['flag'].eq(1)
s = df['flag'].ne(df['flag'].shift()).cumsum()[m]
df.A.map(s.groupby(df.A).value_counts().max(level=0))
print (df)
    A  flag  consecutive_count_max
0   1     1                      3
1   1     1                      3
2   1     0                      3
3   1     1                      3
4   1     1                      3
5   1     1                      3
6   2     0                      3
7   2     1                      3
8   2     1                      3
9   2     0                      3
10  2     1                      3
11  2     1                      3
12  2     1                      3
...