Как я могу получить группу с наибольшей полосой отрицательных чисел в столбце и добавить еще одно условие для фильтрации групп?

Это расширение принятого ответа.

Мой фрейм данных:

import pandas as pd
df = pd.DataFrame(
    {
        'a': [-3, -1, -2, -5, 10, -3, -13, -3, -2, 1, 2, -100],
        'b': [1, 2, 3, 4, 5, 10, 80, 90, 100, 99, 1, 12]
    }
)

Ожидаемый результат:

      a    b
5    -3   10
6   -13   80
7    -3   90
8    -2  100

Логика:

а) Выбор самой длинной серии негативов в a.

б) Если, например, есть две полосы одинакового размера, мне нужна та, у которой сумма b больше. В df есть две полосы размером 4, но мне нужна вторая, потому что сумма b больше.

Моя попытка:

import numpy as np
s = np.sign(df['a'])
df['g'] = s.ne(s.shift()).cumsum()
df['size'] = df.groupby('g')['g'].transform('size')
df['b_sum'] = df.groupby('g')['b'].transform('sum')
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
62
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Код

cond = df['a'] >= 0
grp = cond.cumsum()
idx = (df[~cond].groupby(grp).agg({'a': 'count', 'b': 'sum'})
                .sort_values('b', ascending=False)['a'].idxmax())
out = df[~cond & grp.eq(idx)]

вне:

    a    b
5  -3   10
6 -13   80
7  -3   90
8  -2  100
Ответ принят как подходящий

Вы можете сохранить ту же логику, просто добавьте один дополнительный шаг фильтрации (например, с помощью запроса ), чтобы получить все максимальные размеры, прежде чем получить idxmax суммы «b»:

# negative numbers
m = df['a'].lt(0)
# form groups
g = m.ne(m.shift()).cumsum()

out = df[g.eq(df.groupby(g)['b'].agg(['size', 'sum'])
                .query('size == size.max()')['sum'].idxmax())]

Выход:

    a    b
5  -3   10
6 -13   80
7  -3   90
8  -2  100

Средний:

df.groupby(g)['b'].agg(['size', 'sum'])

   size  sum
a           
1     4   10
2     1    5
3     4  280
4     2  100
5     1   12

Или, используя ваш подход (обратите внимание, что это не гарантирует уникальную группу, если две или более имеют максимальную длину и одинаковую сумму b):

s = np.sign(df['a'])
g = df.groupby(s.ne(s.shift()).cumsum())

s1 = g['a'].transform('size')
s2 = g['b'].transform('sum')

out = df[s1.eq(s1.max()) & s2.eq(s2.max())]
import numpy as np
import pandas as pd

# Sample DataFrame
df = pd.DataFrame(
    {
        'a': [-3, -1, -2, -5, 10, -3, -13, -3, -2, 1, 2, -100],
        'b': [1, 2, 3, 4, 5, 10, 80, 90, 100, 99, 1, 12]
    }
)

# Determine the groups based on sign changes
m = df['a'] < 0
df['gr'] = gr = m.ne(m.shift()).cumsum()
'''
DataFrame with groups:
      a    b  gr
0    -3    1   1
1    -1    2   1
2    -2    3   1
3    -5    4   1
4    10    5   2
5    -3   10   3
6   -13   80   3
7    -3   90   3
8    -2  100   3
9     1   99   4
10    2    1   4
11 -100   12   5

'''
# Calculate the size of each group where 'a' is negative
gr_size = df.loc[m, 'gr'].value_counts()
'''
Group sizes where 'a' is negative:
gr
1    4
3    4
5    1
'''
# Filter DataFrame for the group with the maximum size
res = df[df['gr'] == gr_size.idxmax()]
'''
Filtered DataFrame for largest group size:
   a  b  gr
0 -3  1   1
1 -1  2   1
2 -2  3   1
3 -5  4   1
'''
# Aggregate statistics for each group
gr_stats = df[m].groupby('gr').agg(size=('gr', 'size'), b_sum=('b', 'sum'))
'''
Group statistics:
    size  b_sum
gr             
1      4     10
3      4    280
5      1     12
'''
# Find the group with the maximum b_sum
max_b_sum_group = gr_stats['b_sum'].idxmax()
'''
Group with maximum b_sum: 3
'''
# Display the rows of the group with maximum b_sum
result = df[df['gr'] == max_b_sum_group]
'''
Rows of the group with maximum b_sum:
    a    b  gr
5  -3   10   3
6 -13   80   3
7  -3   90   3
8  -2  100   3
'''

Другие вопросы по теме