在Pandas Groupby和Agg中保留一列但使用其他列

时间:2018-07-28 14:41:29

标签: python pandas

我的目标是按某个列(标识符)对数据集进行分组,然后执行一些自定义操作(首先按日期排序,然后合并状态)。

这是我到目前为止所做的。

import pandas as pd
from io import StringIO
text = """date  identifier  status
1/1/18  A   Pending
1/1/18  B   Pending
1/1/18  C   Pending
1/2/18  A   Approve
1/2/18  B   Pending
1/2/18  C   Pending
1/3/18  B   Approve
1/3/18  C   Pending"""
text = StringIO(text)
df = pd.read_csv(text, sep="\t") 

# group by identifier 
# within the group, sort by date
# then concatenate by status

def myfunc(df):
    df.sort_values(by="date", ascending=True)
    res = [s[0] for s in df['status']]
    return ''.join(res)

df.groupby(['identifier']).agg(lambda x: myfunc(x))

id  date  status        
A   PA  PA
B   PPA PPA
C   PPP PPP

似乎agglambda函数应用于每一列,并且当应用于每一列时,整个组将可见,从而导致status和{{ 1}}存在于最终结果中,并且共享相同的输出。 我可以在之后删除日期列,但看起来并不理想

我尝试指定状态列,然后您将看不到要包括(用于排序)的其他列。

date

总而言之,我应该如何正确使用agg函数以获得最终结果

def myfunc1(x):
print(x)

df.groupby(['identifier']).agg({'status': lambda x: myfunc1(x)}) 
0    Pending
3    Approve
Name: status, dtype: object
1    Pending
4    Pending
6    Approve
Name: status, dtype: object
2    Pending
5    Pending
7    Pending
Name: status, dtype: object

1 个答案:

答案 0 :(得分:3)

IIUC,您可以先切片,然后agg

df['letter'] = df.status.str[0]
df.groupby('identifier').letter.agg(''.join)

identifier
A     PA
B    PPA
C    PPP

但是,如果您真的想使用myfunc,则可以通过执行以下操作来纠正此问题

  1. 重新分配sort_values(或将其完全删除):现在,您正在排序,但未使用sort_values的返回值。因此,实际上什么也没做。 (我相信您应该先sort_values,再进入groupbyagg,而不要进入agg func

  2. 指定您要agg的{​​{1}}列,而不是所有列。您可以通过以下两种方式进行操作,如下所示

代码如下:

status

def myfunc(ser):
    res = [s[0] for s in ser]
    return ''.join(res)

df = df.sort_values('date', ascending=True)
df.groupby(['identifier']).agg({'status': lambda x: myfunc(x)})