Как я могу изменить значения столбца, если номер группы больше N?

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

import pandas as pd
df = pd.DataFrame(
    {
        'a': ['a', 'a', 'a', 'b', 'c', 'x', 'j', 'w'],
        'b': [1, 1, 1, 2, 2, 3, 3, 3],
    }
)

Ожидаемый результат — изменение столбца a:

     a  b  
0    a  1  
1    a  1  
2    a  1  
3  NaN  2  
4  NaN  2  
5  NaN  3  
6  NaN  3  
7  NaN  3  

Логика:

Группы основаны на b. Если для группы df.a.nunique() > 1, то df.a == np.nan.

Это моя попытка. Это работает, но мне интересно, есть ли однострочный/более эффективный способ сделать это:

df['x'] = df.groupby('b')['a'].transform('nunique')
df.loc[df.x > 1, 'a'] = np.nan
Почему в 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
74
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Возможное решение:

g = df.groupby('b')

pd.concat(
    [y if y['a'].eq(y['a'].iloc[0]).all()
     else y.assign(a = np.nan)
     for _, y in g])

Выход:

     a  b
0    a  1
1    a  1
2    a  1
3  NaN  2
4  NaN  2
5  NaN  3
6  NaN  3
7  NaN  3

Один вкладыш с использованием .where в столбце «a», чтобы установить значение np.nan, если nunique != 1:

df["a"] = df["a"].where(df.groupby("b")["a"].transform("nunique") == 1, np.nan)

Выход:

     a  b
0    a  1
1    a  1
2    a  1
3  NaN  2
4  NaN  2
5  NaN  3
6  NaN  3
7  NaN  3
Ответ принят как подходящий

Более эффективно, чем группировать по , использовать дублированный с keep=False и логическое индексирование:

df.loc[~df[['a', 'b']].duplicated(keep=False), 'a'] = float('nan')

Если вы действительно хотите использовать groupby.transform:

df.loc[df.groupby('b')['a'].transform('nunique')>1, 'a'] = float('nan')

Выход:

     a  b
0    a  1
1    a  1
2    a  1
3  NaN  2
4  NaN  2
5  NaN  3
6  NaN  3
7  NaN  3

Я бы использовал простой .loc:

df.loc[df.groupby("b")["a"].transform("nunique").ne(1), "a"] = np.nan
print(df)

Распечатки:

     a  b
0    a  1
1    a  1
2    a  1
3  NaN  2
4  NaN  2
5  NaN  3
6  NaN  3
7  NaN  3

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