Фильтрация Dataframe на основе множества условий - PullRequest
3 голосов
/ 30 мая 2020

вот моя проблема:

У меня есть 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 году у Хилари лучший результат (США), поэтому она будет выбрана. У Тедди второй лучший результат в 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 ]

2 голосов
/ 30 мая 2020

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 голос
/ 30 мая 2020

Вы можете сгруппировать по списку, используя следующий код:

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

EDIT:

На основе новой информации вот решение. Возможно, его можно немного улучшить, но это работает.

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
0 голосов
/ 30 мая 2020

Я использовал другой более длинный подход, который пока никто не представил.

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)

Это немного запутано, но работает.

0 голосов
/ 30 мая 2020
df.groupby(['Country','Name','Date'])['Score'].agg(Score=('Score','first')).reset_index().drop_duplicates(subset='Country', keep='first')

результат

enter image description here

...