[英]Filter Dataframe Based on Highest and Lowest Row Values with Increasing Timeline
我有以下 dataframe 的学生,他们在不同日期的考试成绩(排序):
df = pd.DataFrame({'student': 'A A A A B B B C C D D'.split(),
'exam_date':[datetime.datetime(2013,4,1),datetime.datetime(2013,6,1),
datetime.datetime(2013,7,1),datetime.datetime(2013,9,2),
datetime.datetime(2013,10,1),datetime.datetime(2013,11,2),
datetime.datetime(2014,2,2),datetime.datetime(2014,5,2),
datetime.datetime(2014,6,2), datetime.datetime(2013,7,1),
datetime.datetime(2013,9,2),],
'score': [15, 22, 32, 20, 30, 38, 26, 18, 30, 33, 40]})
print(df)
student exam_date score
0 A 2013-04-01 15
1 A 2013-06-01 22
2 A 2013-07-01 32
3 A 2013-09-02 20
4 B 2013-10-01 30
5 B 2013-11-02 38
6 B 2014-02-02 26
7 C 2014-05-02 18
8 C 2014-06-02 30
9 D 2013-07-01 33
10 D 2013-09-02 40
我只需要保留那些最高分数从最低分数增加超过 10 的行,否则将其丢弃。 在这里,日期也很重要。 最高分必须在后一个日期而不是前一个日期。
例如,对于学生A
,最低分数是15
,分数增加到32
(在日期后面),所以我们将保留它。
对于学生B
,最低分数是26
,但之后分数没有增加。 它基本上减少了,所以我们要放弃它。
对于学生C
,最低分数是33
,分数提高到40
,只增加7
,所以我们要放弃它。
我首先尝试df.groupby('student').agg({'score': np.ptp})
但很难跟踪分数是降低还是提高。
然后我尝试使用df.loc[df.groupby('student')['score'].idxmin()]
和df.loc[df.groupby('student')['score'].idxmax()]
获取最小值和值,但不确定如何比较日期。 也许我将它们合并然后比较,但它的工作量太大了。
所需的 output:
student exam_date score
2 A 2013-07-01 32
8 C 2014-06-02 30
#--For A, highest score of 32 increased by 17 from lowest score of 15
#--For C, highest score of 30 increased by 12 from lowest score of 18
最聪明的做法是什么? 任何建议,将不胜感激。 谢谢!
因此,在您的情况下,首先按最小点过滤
con1 = df.groupby('student')['score'].transform('idxmin')
out = df[df.index>con1].set_index('exam_date').groupby('student')['score'].agg(['idxmax','max'])
out
Out[65]:
idxmax max
student
A 2013-07-01 32
C 2014-06-02 30
假设您的 dataframe 已经按日期排序:
highest_score = lambda x: x['score'].cummax() * (x['score'] > x['score'].shift()) \
- (x['score'].cummin()) >= 10
out = df[df.groupby('student').apply(highest_score).droplevel(0)]
print(out)
# Output:
student exam_date score
2 A 2013-07-01 32
8 C 2014-06-02 30
如果下一个值低于当前最大值,则表达式* (x['score'] > x['score'].shift())
避免传播cummax
。
这个问题有点令人困惑,但这适用于您的示例数据:
subset = df.loc[df.groupby('student').apply(lambda x: x['score'].idxmax() if x.sort_values('exam_date')['score'].diff().max() >= 10 else None).dropna().astype(int)]
Output:
>>> subset
student exam_date score
2 A 2013-07-01 32
8 C 2014-06-02 30
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.