Pandas Groupby несколько столбцов - топ N - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть забавный!И я попытался найти повторяющийся вопрос, но безуспешно ...

Мой фрейм данных состоит из всех Соединенных Штатов и территорий за 2013-2016 годы с несколькими атрибутами.

>>> df.head(2)
     state  enrollees  utilizing  enrol_age65  util_age65  year
1  Alabama     637247     635431       473376      474334  2013
2   Alaska      30486      28514        21721       20457  2013

>>> df.tail(2)
     state               enrollees  utilizing  enrol_age65  util_age65  year
214  Puerto Rico          581861     579514       453181      450150  2016
215  U.S. Territories      24329      16979        22608       15921  2016

Я хочу сгруппировать по году и штату и показать три верхних штата (по количеству «зачисленных» или «использующих» - не имеет значения) для каждого года.

Желаемый результат:

                                       enrollees  utilizing
year state                                                 
2013 California                          3933310    3823455
     New York                            3133980    3002948
     Florida                             2984799    2847574
...
2016 California                          4516216    4365896
     Florida                             4186823    3984756
     New York                            4009829    3874682

До сих пор я пробовал следующее:

df.groupby(['year','state'])['enrollees','utilizing'].sum().head(3)

, что дает только первые 3 строки в объекте GroupBy:

                 enrollees  utilizing
year state                           
2013 Alabama        637247     635431
     Alaska          30486      28514
     Arizona        707683     683273

Я также пробовал лямбда-функцию:

df.groupby(['year','state'])['enrollees','utilizing']\
  .apply(lambda x: np.sum(x)).nlargest(3, 'enrollees')

, которая дает абсолютную наибольшую 3 в объекте GroupBy:

                 enrollees  utilizing
year state                           
2016 California    4516216    4365896
2015 California    4324304    4191704
2014 California    4133532    4011208

Я думаю, что это может потребоватьсяделать с индексированием объекта GroupBy, но я не уверен ... Любое руководство будет оценено!

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Ну, вы могли бы сделать что-то не очень красивое.

Сначала получите список уникальных лет, используя set():

years_list = list(set(df.year))

Создайте фиктивный фрейм данных и функцию, чтобы объединить этоЯ сделал в прошлом:

def concatenate_loop_dfs(df_temp, df_full, axis=0):
    """
    to avoid retyping the same line of code for every df.
    the parameters should be the temporary df created at each loop and the concatenated DF that will contain all
    values which must first be initialized (outside the loop) as df_name = pd.DataFrame(). """ 

if df_full.empty:
    df_full = df_temp
else:
    df_full = pd.concat([df_full, df_temp], axis=axis)

return df_full

создание фиктивного финала df

df_final = pd.DataFrame()

Теперь вы будете повторять цикл каждый год и переходить к новому DF:

for year in years_list:
    # The query function does a search for where
    # the @year means the external variable, in this case the input from loop
    # then you'll have a temporary DF with only the year and sorting and getting top3
    df2 = df.query("year == @year")

    df_temp = df2.groupby(['year','state'])['enrollees','utilizing'].sum().sort_values(by="enrollees", ascending=False).head(3)
    # finally you'll call our function that will keep concating the tmp DFs
    df_final = concatenate_loop_dfs(df_temp, df_final)

и готово.

print(df_final)
0 голосов
/ 08 февраля 2019

Затем вам нужно отсортировать объект GroupBy .sort_values('enrollees), ascending=False

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...