假设我有以下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的列,即

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


编辑:我希望能有一个更通用的解决方案(不仅仅是我们有NaN值),而且如果我们想指定q的值作为将要包含或不包含的阈值。

最佳答案

我认为需要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)})


编辑1:

功能上也可以进行过滤,以避免丢失不匹配的组:

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]

关于python - 在 Pandas 的聚合中应用过滤器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52497214/

10-09 20:21
查看更多