根据多种条件过滤数据框

时间:2020-05-29 23:39:29

标签: python pandas time-series

这是我的问题:

我有一个像这样的dataFrame:

Date  Name  Score  Country
2012  Paul    45    Mexico
2012  Mike    38    Sweden
2012  Teddy   62    USA 
2012  Hilary  80    USA 
2013  Ashley  42    France 
2013  Temari  58    UK 
2013  Harry   78    UK
2013  Silvia  55    Italy

我想选择两个最佳分数,并按日期和来自不同国家/地区进行筛选。

例如此处:2012年,希拉里(Hilary)获得最佳成绩(美国),因此她将入选。 泰迪(Teddy)在2012年获得第二高分,但由于来自同一个国家(美国),他不会被选中 因此,保罗将因来自其他国家(墨西哥)而被选中。

这就是我所做的:

df = pd.DataFrame(
    {'Date':["2012","2012","2012","2012","2013","2013","2013","2013"],
     'Name': ["Paul", "Mike", "Teddy", "Hilary", "Ashley", "Temaru","Harry","Silvia"],
     'Score': [45, 38, 62, 80, 42, 58,78,55],
     "Country":["Mexico","Sweden","USA","USA","France","UK",'UK','Italy']})

然后我按日期和分数进行过滤:

df1 = df.set_index('Name').groupby('Date')['Score'].apply(lambda grp: grp.nlargest(2))

但是我真的不知道并做一个过滤器,考虑到它们必须来自不同的国家。

有人对此有想法吗?非常感谢

编辑:我正在寻找的答案应该是这样的:

Date  Name  Score  Country
2012  Hilary  80    USA 
2012  Paul    45    Mexico
2013  Harry   78    UK
2013  Silvia  55    Italy

按日期,最佳分数和来自不同国家/地区过滤两个人

4 个答案:

答案 0 :(得分:2)

sort_values + tail

s=df.sort_values('Score').drop_duplicates(['Date','Country'],keep='last').groupby('Date').tail(2)
s
   Date    Name  Score Country
0  2012    Paul     45  Mexico
7  2013  Silvia     55   Italy
6  2013   Harry     78      UK
3  2012  Hilary     80     USA

答案 1 :(得分:1)

您可以使用以下代码对列表进行分组:

df1 = df.set_index('Name').groupby(['Date', 'Country'])['Score'].apply(lambda grp: grp.nlargest(1))

它将发布:

Date  Country  Name     Score
2012  Mexico   Paul      45
      Sweden   Mike      38
      USA      Hilary    80
2013  France   Ashley    42
      Italy    Silvia    55
      UK       Harry     78

编辑:

基于新信息,这是一个解决方案。也许可以对其进行一些改进,但是它可以工作。

df.sort_values(['Score'],ascending=False, inplace=True)
df.sort_values(['Date'], inplace=True)
df.drop_duplicates(['Date', 'Country'], keep='first', inplace=True)
df1 = df.groupby('Date').head(2).reset_index(drop=True)

这将输出

   Date    Name  Score Country
0  2012  Hilary     80     USA
1  2012    Paul     45  Mexico
2  2013   Harry     78      UK
3  2013  Silvia     55   Italy

答案 2 :(得分:0)

df.groupby(['Country','Name','Date'])['Score'].agg(Score=('Score','first')).reset_index().drop_duplicates(subset='Country', keep='first')

结果

enter image description here

答案 3 :(得分:0)

我使用了其他更长的方法,到目前为止还没有人提交。

df = pd.DataFrame(
    {'Date':["2012","2012","2012","2012","2013","2013","2013","2013"],
     'Name': ["Paul", "Mike", "Teddy", "Hilary", "Ashley", "Temaru","Harry","Silvia"],
     'Score': [45, 38, 62, 80, 42, 58,78,55],
     "Country":["Mexico","Sweden","USA","USA","France","UK",'UK','Italy']})

df1=df.groupby(['Date','Country'])['Score'].max().reset_index()

df2=df.iloc[:,[1,2]]

df1.merge(df2)

这有点令人费解,但是可以完成工作。