我有以下學生的資料框,他們的考試成績在不同日期(排序):
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 的行,否則洗掉它們。在這里,日期也很重要。最高分必須在后一個日期比前一個日期。
例如,對于 student A,最低分數是15并且分數增加到32(日期的后面),所以我們要保留它。
對于學生來說B,最低分是26,但之后沒有增加分數。它基本上減少了,所以我們要放棄它。
對于學生D,最低分是33,分數增加到40,只增加7,所以我們要放棄它。
我第一次嘗試,df.groupby('student').agg({'score': np.ptp})但很難跟蹤分數是減少還是增加。
然后我嘗試使用df.loc[df.groupby('student')['score'].idxmin()]并df.loc[df.groupby('student')['score'].idxmax()]獲取最小值和值,但不確定如何比較日期。也許我將它們合并然后比較,但作業量太大。
期望的輸出:
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
最聰明的做法是什么?任何建議,將不勝感激。謝謝!
uj5u.com熱心網友回復:
假設您的資料框已經按日期排序:
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傳播。
uj5u.com熱心網友回復:
這個問題有點令人困惑,但這適用于您的示例資料:
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)]
輸出:
>>> subset
student exam_date score
2 A 2013-07-01 32
uj5u.com熱心網友回復:
因此,在您的情況下,首先按最小點過濾
df = df[df.index>=df.groupby('student')['score'].transform('idxmin')]
out = df[df.score - df.groupby('student').score.transform('min')>10]
Out[77]:
student exam_date score
2 A 2013-07-01 32
8 C 2014-06-02 30
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/389347.html
