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确定,检查:-)