Pandas groupby: заменить значения в одном столбце перед первым вхождением в другой столбец

Ниже представлен игрушечный фрейм данных Pandas с тремя столбцами: «id» (идентификатор группы), «b» (для условия) и «c» (цель):

df = pd.DataFrame({'id' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2], 
              'b'  : [3,4,5,'A',3,4,'A',1,'A',1,3,'A',2,3], 
              'c'  : [1,0,1,10,1,1,20,1,10,0,1,20,1,1]})
print(df)
    id  b   c
0    1  3   1
1    1  4   0
2    1  5   1
3    1  A  10
4    1  3   1
5    1  4   1
6    1  A  20
7    2  1   1
8    2  A  10
9    2  1   0
10   2  3   1
11   2  A  20
12   2  2   1
13   2  3   1

Для каждой группы я хочу заменить значения в столбце «c» на nan (т. е. np.nan) до первого появления «A» в столбце «b».

Желаемый результат следующий:

desired_output_df = pd.DataFrame({'id' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2], 
                                  'b'  : [3,4,5,'A',3,4,'A',1,'A',1,3,'A',2,3], 
                                  'c'  : [np.nan,np.nan,np.nan,10,1,1,20,np.nan,10,0,1,20,1,1]})
print(desired_output_df)
    id  b     c
0    1  3   NaN
1    1  4   NaN
2    1  5   NaN
3    1  A  10.0
4    1  3   1.0
5    1  4   1.0
6    1  A  20.0
7    2  1   NaN
8    2  A  10.0
9    2  1   0.0
10   2  3   1.0
11   2  A  20.0
12   2  2   1.0
13   2  3   1.0

Я могу получить индекс значений столбца c, которые я хочу изменить, с помощью следующей команды: df.groupby('id').apply(lambda x: x.loc[:(x.b == 'A').idxmax()-1]).index. Но результатом является «MultiIndex», и я не могу использовать его для замены значений.

MultiIndex([(1, 0),
            (1, 1),
            (1, 2),
            (2, 7)],
           names=['id', None])

Заранее спасибо.

Ваш пример, кажется, противоречит вашему описанию. Почему c строки 7 является NaN в желаемом результате?

chrslg 11.02.2023 21:10

В группе с id = 2 строка 7 представляет экземпляр до первого вхождения «A» в столбце b.

IJN81 11.02.2023 21:12

Ох, хорошо! Я пропустил часть «для каждой группы».

chrslg 11.02.2023 21:13
Почему в 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
3
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пытаться:

df['c'] = np.where(df.groupby('id').apply(lambda x: x['b'].eq('A').cumsum()) > 0, df['c'], np.nan)
print(df)

Отпечатки:

    id  b     c
0    1  3   NaN
1    1  4   NaN
2    1  5   NaN
3    1  A  10.0
4    1  3   1.0
5    1  4   1.0
6    1  A  20.0
7    2  1   NaN
8    2  A  10.0
9    2  1   0.0
10   2  3   1.0
11   2  A  20.0
12   2  2   1.0
13   2  3   1.0

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