Python 将条件应用于df.groupby()以筛选出重复项

Python 将条件应用于df.groupby()以筛选出重复项,python,pandas,numpy,Python,Pandas,Numpy,我需要根据条件分组并过滤掉数据帧中的重复项。我的数据框如下所示: import pandas as pd df = pd.DataFrame({'ID':[1,1,2,2,3,4,4],'Date':['1/1/2001','1/1/1999','1/1/2010','1/1/2004','1/1/2000','1/1/2001','1/1/2000'], 'type':['yes','yes','yes','yes','no','no','no'], 'source':[3,1,1,2,2,

我需要根据条件分组并过滤掉数据帧中的重复项。我的数据框如下所示:

import pandas as pd

df = pd.DataFrame({'ID':[1,1,2,2,3,4,4],'Date':['1/1/2001','1/1/1999','1/1/2010','1/1/2004','1/1/2000','1/1/2001','1/1/2000'], 'type':['yes','yes','yes','yes','no','no','no'], 'source':[3,1,1,2,2,2,1]})
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index('ID')
df

    Date    source  type
ID          
1   2001-01-01  3   yes
1   1999-01-01  1   yes
2   2010-01-01  1   yes
2   2004-01-01  2   yes
3   2000-01-01  2   no
4   2001-01-01  2   no
4   2000-01-01  1   no
我需要按ID和类型分组,anywhere type==yes仅当最新记录具有最高的源时才保留它。如果最新记录没有最高的源,则保留这两个记录 期望输出:

    Date    source  type
ID          
1   2001-01-01  3   yes
2   2010-01-01  1   yes
2   2004-01-01  2   yes
3   2000-01-01  2   no
4   2001-01-01  2   no
4   2000-01-01  1   no
我尝试过使用transform,但不知道如何应用条件:

    grouped = df.groupby(['ID','type'])['Date'].transform(max)
    df = df.loc[df['Date'] == grouped]
    df

        Date    source  type
    ID          
    1   2001-01-01  3   yes
    2   2010-01-01  2   yes
    3   2000-01-01  2   no
    4   2001-01-01  2   no
非常感谢您的帮助

这里的问题是,如果我有一个包含更多行的数据帧(我有大约70列和5000行),它没有考虑最大源代码

    Date    source  type
ID          
1   2001-01-01  3   yes
1   1999-01-01  1   yes
2   2010-01-01  1   yes
2   2004-01-01  2   yes
3   2000-01-01  2   no
4   2001-01-01  1   yes
4   2000-01-01  2   yes
使用您的代码,我得到:

Date    source  type
ID          
1   2001-01-01  3   yes
2   2010-01-01  1   yes
2   2004-01-01  2   yes
3   2000-01-01  2   no
4   2001-01-01  1   yes
应该是:

    Date    source  type
ID          
1   2001-01-01  3   yes
2   2010-01-01  1   yes
2   2004-01-01  2   yes
3   2000-01-01  2   no
4   2001-01-01  1   yes
4   2000-01-01  2   yes

这将需要
pd.concat

grouped = df.groupby(['type'])['Date'].transform(max)# I change this line seems like you need groupby type
s = df.loc[df['Date'] == grouped].index

#here we split the df into two part , one need to drop the not match row , one should keep all row    
pd.concat([df.loc[df.index.difference(s)].sort_values('Date').groupby('ID').tail(1),df.loc[s]]).sort_index()
             Date  source type
    ID                        
    1  2001-01-01       3  yes
    2  2010-01-01       1  yes
    2  2004-01-01       2  yes
    3  2000-01-01       2   no
    4  2001-01-01       2   no
    4  2000-01-01       1   no
更新

grouped = df.groupby(['type'])['source'].transform(max)
s = df.loc[df['source'] == grouped].index

    pd.concat([df.loc[s].sort_values('Date').groupby('ID').tail(1),df.loc[df.index.difference(s)]]).sort_index()
Out[445]: 
          Date  source type
ID                         
1   2001-01-01       3  yes
2   2010-01-01       1  yes
2   2004-01-01       2  yes
3   2000-01-01       2   no
4   2001-01-01       1  yes
4   2000-01-01       2  yes

这将需要
pd.concat

grouped = df.groupby(['type'])['Date'].transform(max)# I change this line seems like you need groupby type
s = df.loc[df['Date'] == grouped].index

#here we split the df into two part , one need to drop the not match row , one should keep all row    
pd.concat([df.loc[df.index.difference(s)].sort_values('Date').groupby('ID').tail(1),df.loc[s]]).sort_index()
             Date  source type
    ID                        
    1  2001-01-01       3  yes
    2  2010-01-01       1  yes
    2  2004-01-01       2  yes
    3  2000-01-01       2   no
    4  2001-01-01       2   no
    4  2000-01-01       1   no
更新

grouped = df.groupby(['type'])['source'].transform(max)
s = df.loc[df['source'] == grouped].index

    pd.concat([df.loc[s].sort_values('Date').groupby('ID').tail(1),df.loc[df.index.difference(s)]]).sort_index()
Out[445]: 
          Date  source type
ID                         
1   2001-01-01       3  yes
2   2010-01-01       1  yes
2   2004-01-01       2  yes
3   2000-01-01       2   no
4   2001-01-01       1  yes
4   2000-01-01       2  yes


您想要的输出似乎有一条额外的记录(第三条)。@cᴏʟᴅsᴘᴇᴇᴅ 这是我想要的输出。条件为anywhere type==是仅当最新记录具有最高源时才保留该记录。如果最新的记录没有最高来源,请保留两个记录,这与您所说的略有不同(以及我对您所说内容的解释),但好的,谢谢您的澄清。我很抱歉,我修正了问题中条件的措辞。我的答案有什么问题吗?你想要的输出似乎有一个额外的记录(第三个)。@cᴏʟᴅsᴘᴇᴇᴅ 这是我想要的输出。条件为anywhere type==是仅当最新记录具有最高源时才保留该记录。如果最新的记录没有最高来源,请保留两个记录,这与您所说的略有不同(以及我对您所说内容的解释),但好的,谢谢您的澄清。我很抱歉,我修正了问题中条件的措辞。我的回答有什么问题吗?尽管这再现了所需的输出,但规模并没有扩大。如果我按照ID 2的相同格式再添加两行,它只保留最新的日期。它不是根据我上面需要的条件进行过滤。我将用一个例子更新我的问题。它没有过滤出正确的行。请看应该在我更新的问题的底部。我真的很感激你的帮助effort@Chris这一个
pd.concat([df.loc[s].sort_值('Date').groupby('ID').tail(1),df.loc[df.index.difference(s)])。sort_index()
;它返回
ID1,1,2,3,4,4
它应该返回
ID1,2,2,3,4,4
请再看一看更新问题中的最后一个输出。@Chris确定,检查:-)虽然这会复制所需的输出,但不会以更大的规模复制。如果我按照ID 2的相同格式再添加两行,它只保留最新的日期。它不是根据我上面需要的条件进行过滤。我将用一个例子更新我的问题。它没有过滤出正确的行。请看应该在我更新的问题的底部。我真的很感激你的帮助effort@Chris这一个
pd.concat([df.loc[s].sort_值('Date').groupby('ID').tail(1),df.loc[df.index.difference(s)])。sort_index()
;它返回
ID1,1,2,3,4,4
它应该返回
ID1,2,2,3,4,4
请重新查看更新问题中的最后一个输出。@Chris确定,检查:-)