Применить фильтр в агрегации в пандах

1

Скажем, у меня есть следующий pd.DataFrame.

import pandas as pd
import numpy as np

data = {'number': [1, 1, 1, 2],  'q':[np.nan, 2, np.nan, 1], 'letter': ['alpha', 'beta', 'gamma', 'alpha']}
df = pd.DataFrame(data)

   number   q   letter
0   1      NaN   alpha
1   1      2.0   beta
2   1      NaN   gamma
3   2      1.0   alpha

То, что я хочу сделать, - это объединить по числу и создать список со всеми буквами и применить фильтр, основанный на значении q.

Если я это сделаю:

df.groupby('number').agg({"letter": lambda w: list(w) }) даст:

    letter
number  
1   [alpha, beta, gamma]
2   [alpha]

Но я хочу включить только столбцы, чтобы соответствующее значение q не было NaN, т. NaN

  number    letter
0   1       [beta]
1   2       [alpha]

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

Теги:
pandas
aggregation

1 ответ

3
Лучший ответ

Мне кажется, нужен DataFrame.dropna:

df1 = df.dropna().groupby('number').agg({"letter": lambda w: list(w)})

Если хотите указать столбец для удаления отсутствующих значений:

df1 = df.dropna(subset=['q']).groupby('number').agg({"letter": lambda w: list(w)})
print (df1)
         letter
number         
1        [beta]
2       [alpha]

РЕДАКТИРОВАТЬ:

Вы также можете фильтровать по query:

df1 = df.query("q > 0").groupby('number').agg({"letter": lambda w: list(w)})

Или boolean indexing:

df1 = df[df['q'] > 0].groupby('number').agg({"letter": lambda w: list(w)})

df1 = df[df['q'].notnull()].groupby('number').agg({"letter": lambda w: list(w)})

EDIT1:

Фильтрация возможна также в функции, чтобы избежать потери несогласованных групп:

def f(x):
    return x.loc[x['q'] > 1, 'letter'].tolist()

df2 = df.groupby('number').apply(f).reset_index(name='val')
print (df2)
   number     val
0       1  [beta]
1       2      []

df1 = df[df['q'] > 1].groupby('number').agg({"letter": lambda w: list(w)})
print (df1)
        letter
number        
1       [beta]
  • 0
    Спасибо за ответ, но мне нужно что-то более общее. Например, если значение q больше указанного числа. Большое спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню