簡體   English   中英

基於最高和最低行值以及時間線增加過濾 Dataframe

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM