pandas panda在grouby后按日期时间范围过滤

pkln4tw6  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(155)

我想计算一下每个学生每门课的分数在一段时间内的变化。
例如:
这是原始表
| 日期时间|学生|主题|得分|
| - -|- -|- -|- -|
| 2021年1月1日|A级|数学|七十个|
| 2021年3月1日|A级|物理学I|八十个|
| 2021年2月1日|A级|物理学I|八十个|
| 2021年2月15日|A级|数学|九十|
| 2021年2月1日|B|物理学I|九十五个|
| 2021年2月11日|A级|物理学I|九十|
| 2021年5月15日|A级|物理学I|八十个|
| 2021年2月1日|B|数学|八十个|
| 2021年2月1日|A级|数学|100个|
| 一个人。|一个人。|一个人。|一个人。|
这是一个先按学生排序,然后按主题排序的表。
| 日期时间|学生|主题|得分|
| - -|- -|- -|- -|
| 2021年1月1日|A级|数学|七十个|
| 2021年2月1日|A级|数学|100个|
| 2021年2月15日|A级|数学|九十|
| 2021年2月1日|A级|物理学I|八十个|
| 2021年2月11日|A级|物理学I|九十|
| 2021年3月1日|A级|物理学I|八十个|
| 2021年5月15日|A级|物理学I|八十个|
| 2021年2月1日|B|数学|八十个|
| 2021年2月1日|B|物理学I|九十五个|
| 一个人。|一个人。|一个人。|一个人。|
假设这里是一个时间段序列[2021- 01 - 01 ~ 2021-02-10,2021-02-14 ~ 2021-02-17]
对于学生A,数学科目,时间段“2020-01-01 ~ 2021-02-10”,分数的变化为
| 日期时间|学生|主题|得分|
| - -|- -|- -|- -|
| 2021年1月1日|A级|数学|不含N|
| 2021年2月1日|A级|数学|30个|
对于学生A,物理一科,时间段“2020-01-01 ~ 2021-02-10”,分数变化为
| 日期时间|学生|主题|得分|
| - -|- -|- -|- -|
| 2021年2月1日|A级|物理学I|不含N|
对于学生A,数学科目,时间段“2020-02-14 ~ 2021-02-17”,分数的变化为
| 日期时间|学生|主题|得分|
| - -|- -|- -|- -|
| 2021年2月15日|A级|数学|不含N|
我的第一次尝试是如此缓慢,以至于我使用了如此多的for循环来计算如下

period_time = [(pd.to_datetime(2021-01-01), pd.to_datetime(2021-02-10))]

students = df['Student'].unique()
for student in students:
    student_table = df.loc[df['Student'] == student]

    subjects = student_table['Subject'].unique()
    for subject in subjects:
        subject_table = student_table.loc[student_table['Subject'] == subject]

        for time in period_time:
            start = time[0]
            end   = time[1]
            res_table = subject_table.loc[ (start <= subject_table['Datetime']) & 
                                           (subject_table['Datetime'] <= end)]
            diff = res_table['Score'].diff()

然后我尝试使用内置函数“groupby "对”Student“和”Subject“进行如下分类

df.groupby(['Student', 'Subject'], group_keys = False)

然而,我不知道我应该如何分类的日期时间给一个特定的时期时间。任何建议都是感激的!

a11xaf1n

a11xaf1n1#

DataFrameGroupBy.diff之前使用Series.between进行筛选,并仅分配筛选的行:

df['Datetime'] = pd.to_datetime(df['Datetime'])

df = df.sort_values(['Student','Subject'])

period_time = [(pd.to_datetime('2021-01-01'), pd.to_datetime('2021-02-10')),
               (pd.to_datetime('2021-02-14'), pd.to_datetime('2021-02-17'))]

for (start, end) in period_time:
    m = df['Datetime'].between(start, end)
    df.loc[m, 'Score'] = df[m].groupby(['Student', 'Subject'])['Score'].diff()

print (df)
    Datetime Student    Subject  Score
0 2021-01-01       A       Math    NaN
3 2021-02-15       A       Math    NaN
8 2021-02-01       A       Math   30.0
1 2021-03-01       A  Physics I   80.0
2 2021-02-01       A  Physics I    NaN
5 2021-02-11       A  Physics I   90.0
6 2021-05-15       A  Physics I   80.0
7 2021-02-01       B       Math    NaN
4 2021-02-01       B  Physics I    NaN

如果需要列只带有count新值:

for (start, end) in period_time:
    m = df['Datetime'].between(start, end)
    df.loc[m, 'Score_new'] = df[m].groupby(['Student', 'Subject'])['Score'].diff()

print (df)
    Datetime Student    Subject  Score  Score_new
0 2021-01-01       A       Math     70        NaN
3 2021-02-15       A       Math     90        NaN
8 2021-02-01       A       Math    100       30.0
1 2021-03-01       A  Physics I     80        NaN
2 2021-02-01       A  Physics I     80        NaN
5 2021-02-11       A  Physics I     90        NaN
6 2021-05-15       A  Physics I     80        NaN
7 2021-02-01       B       Math     80        NaN
4 2021-02-01       B  Physics I     95        NaN

相关问题