从 Python 中的分组数据中查找最大值

Finding max from grouped data in Python

我有一个显示每天用餐次数的数据集。周列显示该日期属于一个月中的哪一周。请参阅下面的数据集示例:

Id.        date.               Meals   Week
 1        2020-02-23            1         4
 1        2020-02-24            1         5
 1        2020-02-25            2         5
 1        2020-02-27            1         5
 1        2020-01-03            2         1
...         ...                ...       ...
 2        2020-03-04            3         2
 2        2020-03-05            4         2
 2        2020-03-06            3         2
 2        2020-03-07            1         2
 2        2020-03-08            2         2

我根据参与者 ID 和周对数据进行分组,以便获得每个参与者每周的平均用餐次数。请看下面:

d = data[['Id','Week','Meals']].groupby(['Id', 'Week'],sort=False ).agg('mean')

                                 Meals
               ID          Week
                1           4   1.400000
                            5   1.333333
                            1   2.000000
                            2   1.250000
                            3   1.000000
                2           2   2.000000
                            3   2.142857
                            4   2.500000
                            5   2.500000
                3           2   2.555556
                            3   2.600000
                            4   1.833333
                            5   2.000000
                            1   2.000000

我的第一个问题:

  1. 如果每个参与者的最大进餐次数是在第一周或上周。

Richie 回答后,输出:

print(df.head(50).to_dict('split')

{'index': [('"55eb3fea748092000daa9b25"', 4), ('"55eb3fea748092000daa9b25"', 5), ('"55eb3fea748092000daa9b25"', 1), ('"55eb3fea748092000daa9b25"', 2), ('"55eb3fea748092000daa9b25"', 3)], 'columns': ['Meals'], 'data': [[1.4], [1.3333333333333333], [2.0], [1.25], [1.0]]}

我的第二个问题(在更新我的 post 之后)是:

  1. 最长的一周是哪一周? 请注意,该研究进行了 1-4/5 周。所以输出看起来像这样,有一个额外的列称为(研究周):

输出:

                                Meals      max_week
Id  Week    Week of the study       
1    4            1               1          FALSE
     5            2               1          FALSE
     1            3               2          TRUE
     2            4               1          FALSE
     3            5               1          FALSE
2    2            1               2          FALSE
     3            2               2          FALSE
     4            3               2          TRUE
     5            4               2          TRUE
3    2            1               2          FALSE
     3            2               2          TRUE
     4            3               2          FALSE
     5            4               3          FALSE
     1            5               3          FALSE

然后我只想保存 ID、学习周数和零食,如下所示:

                                 Meals    max_week
ProlificId  Week of the study       
    1              3                2       TRUE
    2              3                2       TRUE
    2              4                2       TRUE
    3              2                2       TRUE

非常感谢您的帮助 正书

看来你只需要找到每个 Id 的最大平均膳食数 Week of the study

取下面的例子

import pandas as pd
import numpy as np

# sample data
# please always provide a callable line of code with your data
# you can get it with df.head(10).to_dict('split')
# read more about this in 
# and 
np.random.seed(123) # include when creating random sample
days, people = 18, 2
data = pd.DataFrame({
    'Id': [i for _ in range(days) for i in range(1, people + 1)],
    'Date': pd.date_range('2020-02-23', periods=days).repeat(people).values,
    'Meals': np.random.randint(1, 5, days * people),
})
# data['Week_of_month'] = (data['Date'].dt.day - 1) // 7 + 1
data['Week_of_the_study'] = data['Date'].dt.isocalendar().week
data['Week_of_the_study'] -= data['Week_of_the_study'].min() - 1
print(data)

    Id       Date  Meals  Week_of_the_study
0    1 2020-02-23      3                  1
1    2 2020-02-23      2                  1
2    1 2020-02-24      3                  2
3    2 2020-02-24      3                  2
4    1 2020-02-25      1                  2
5    2 2020-02-25      3                  2
6    1 2020-02-26      3                  2
7    2 2020-02-26      2                  2
8    1 2020-02-27      4                  2
9    2 2020-02-27      3                  2
10   1 2020-02-28      4                  2
11   2 2020-02-28      2                  2
12   1 2020-02-29      3                  2
13   2 2020-02-29      2                  2
14   1 2020-03-01      1                  2
15   2 2020-03-01      2                  2
16   1 2020-03-02      3                  3
17   2 2020-03-02      4                  3
18   1 2020-03-03      2                  3
19   2 2020-03-03      1                  3
20   1 2020-03-04      3                  3
21   2 2020-03-04      1                  3
22   1 2020-03-05      4                  3
23   2 2020-03-05      2                  3
24   1 2020-03-06      4                  3
25   2 2020-03-06      3                  3
26   1 2020-03-07      2                  3
27   2 2020-03-07      1                  3
28   1 2020-03-08      1                  3
29   2 2020-03-08      1                  3
30   1 2020-03-09      1                  4
31   2 2020-03-09      2                  4
32   1 2020-03-10      4                  4
33   2 2020-03-10      4                  4
34   1 2020-03-11      3                  4
35   2 2020-03-11      1                  4

和代码

max_weeks = ( # get average meals per week & Id
    data.groupby(['Id', 'Week_of_the_study'])
    ['Meals'].mean()
).rename('max_meals')

max_weeks = max_weeks.loc[ # filter only weeks with highest avg meals
    max_weeks == max_weeks.groupby('Id').transform(max)
].to_frame()

输出

                      max_meals
Id Week_of_the_study
1  1                   3.000000
2  2                   2.428571

旧答案

您可以在当前输出后使用 groupby.transform 来获得最大周数。

d = data.groupby(['ProlificId', 'Week'])['Snacks'].mean().to_frame()

# most use cases want to separate by year/month as well, in that case use
# data['date'] = pd.to_datetime(data['date'])
# data['Year'] = data['date'].dt.year
# data['Month'] = data['date'].dt.month
# d = data.groupby(['ProlificId', 'Year', 'Month', 'Week'])['Snacks'].mean().to_frame()

d['max_week'] = d == d.groupby('ProlificId').transform(max)

输出

                   Snacks  max_week
ProlificId Week
1          1     2.000000      True
           4     1.000000     False
           5     1.333333     False
2          2     2.600000      True