Фильтрация DataFrame для дублированных элементов и вычисление групповых средств по результату - PullRequest
0 голосов
/ 20 ноября 2018

Хорошо, вот что я пытаюсь сделать:

У меня есть такой DataFrame:

data = pd.DataFrame(
{'a' : [1,1,1,2,2,3,3,3],
 'b' : [23,45,62,24,45,34,25,62],
 })

Мне удалось вычислить среднее значение столбца 'a' сгруппированногопо столбцу 'b', используя следующий код:

data.groupby('b', as_index=False)['a'].mean()

, что привело к созданию следующего кадра данных:

current DataFrame

Тем не менее, я хотел бы рассчитать только среднее для значений 'b', которые встречаются в DataFrame более одного раза, в результате чего получается такой кадр данных:

Desired DataFrame

Я пытался сделать это, используя следующую строку:

data.groupby('b', as_index=False).filter(lambda group: len(group)>1)['a'].mean()

, но это приводит к среднему значению строк 1, 2, 4 и 7, что, очевидно, не то, что я хочу.Может кто-нибудь, пожалуйста, помогите мне получить нужный DataFrame и скажите, что я ошибаюсь при использовании функции фильтра?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

Вы можете отфильтровать перед вашим фреймом данных через loc до groupby:

df = pd.DataFrame({'a' : [1,1,1,2,2,3,3,3],
                   'b' : [23,45,62,24,45,34,25,62]})

counts = df['b'].value_counts()

res = df.loc[df['b'].isin(counts[counts > 1].index)]\
        .groupby('b', as_index=False)['a'].mean()

print(res)

    b    a
0  45  1.5
1  62  2.0
0 голосов
/ 20 ноября 2018

Группировка по дубликатам

Вы можете сделать это с помощью data['b'].duplicated(keep=False), чтобы сначала создать логическую маску:

>>> data[data['b'].duplicated(keep=False)].groupby('b', as_index=False)['a'].mean()                                                                         
    b    a
0  45  1.5
1  62  2.0

data.b.duplicated(keep=False) помечает все дублированные вхождения как True и позволяет ограничить выводв эти строки:

>>> data.b.duplicated(keep=False)                                                                                                                        
0    False
1     True
2     True
3    False
4     True
5    False
6    False
7     True
Name: b, dtype: bool

>>> data[data.b.duplicated(keep=False)]                                                                                                                  
   a   b
1  1  45
2  1  62
4  2  45
7  3  62

Обновление: группировка по произвольному числу вхождений

Можно ли обобщить это решение для поиска произвольного числа вхождений?Допустим, я хотел вычислить среднее значение только для значений, которые встречались в DataFrame более 5 раз.

В этом сценарии вам необходимо сгенерировать логическую маску той же формы, что и в примере выше, но используя немного другой подход.

Вот один из способов:

>>> vc = data['b'].map(data['b'].value_counts(sort=False))
>>> vc                                                                                                                                                   

0    1
1    2
2    2
3    1
4    2
5    1
6    1
7    2
Name: b, dtype: int64

Это поэлементное число для каждого элемента b.Чтобы получить это в маске (скажем, вы хотите средство только для count == 2, что аналогично приведенному выше в этом примере, но может быть расширено для любого целого):

mask = vc == 2  # or > 5, in your case
data[mask].groupby('b', as_index=False)['a'].mean()
0 голосов
/ 20 ноября 2018

Вы были довольно близки:

data.groupby('b').filter(lambda g:len(g)>1).groupby('b',as_index=False).mean()

приводит к ответу, который вы искали:

    b    a
0  45  1.5
1  62  2.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...