使用apply后如何从分组元素中获取数据框

How to obtain dataframe from grouped element after using apply

假设这个数据框:

First Name  Last Name   Val1 
George      Clooney      N     
George      Clooney      N   
George      Clooney      Y
George      Freeman      N
George      Freeman      N
Claire      Stark        N
Claire      Stark        Y   

然后目标是产生这个:

First Name  Last Name   Val1  Total
George      Clooney      Y      3
George      Freeman      N      2
Claire      Stark        Y      2

总数 Val1Y 只要其中一个实例是 Y

我的代码如下所示:

grouped = df.groupby(by=['First Name', 'Last Name'])

def val_func(x):
    if (x['Val1'] == 'Y').any():
    return 'Y'
    else:
    return 'N'

cumulative = grouped.apply(val_func)

除了 cumulative 有数据类型 object 并且我只能访问 Val1,也就是说,我无法访问 First NameLast Name(虽然当我 运行 print(cumulative) 时,它会打印所有内容)。

如果我尝试:

df_cumulative = pd.DataFrame(cumulative)

然后,我只得到带有 YN 的列,而不是名称。

如何解决这个问题?而且,我可以return两个参数吗?一份用于 Val1 一份用于 Total?还是我必须 运行 另一个申请 Total 并将该列附加到数据框?

这里有一个方法:

(df.sort_values('Val1')
 .groupby(['First Name','Last Name'])
 .agg(Val1 = ('Val1','last'),count = ('Val1','count'))
 .reset_index())

输出:

  First Name Last Name Val1  count
0     Claire     Stark    Y      2
1     George   Clooney    Y      3
2     George   Freeman    N      2

另一种方法是使用 groupby.agg,如果它存在(因为 Y>N)和 count:[=17=,则使用 max 得到“Y” ]

out = df.groupby(['First Name', 'Last Name'], sort=False, as_index=False)\
        .agg(Val1=('Val1', 'max'), Total=('Val1', 'count'))

输出:

  First Name Last Name Val1  Total
0     George   Clooney    Y      3
1     George   Freeman    N      2
2     Claire     Stark    Y      2

您可以传入一个 select 基于您想要的任何标准的 lambda。例如,以下根据“Y”的数量是否大于“N”的数量来聚合“Val1”(如果有更多的“Y”select "Y" else "N" ):

out = df.groupby(['First Name', 'Last Name'], sort=False, as_index=False)\
        .agg(Val1=('Val1', lambda x: 'Y' if x.eq('Y').sum() > x.eq('N').sum() else 'N'), 
             Total=('Val1', 'count'))