我有一個用于每周培訓課程的資料框和一個用于參加者在這些培訓課程中提交的評估的資料框。
每個資料框都有一個日期列 - 對于會話,它是會話發生的日期。對于評估,它是提交評估的日期。與會者可能會參加多個會議,因此將提交多個評估。
我需要將每個評估與特定會話聯系起來。他們可能在會議的同一天提交了評估,在這種情況下,匹配很容易。但他們可以在下一次培訓之前的任何一天提交評估。
對于評估 df 中的每個日期,我需要回傳最接近評估日期但不在評估日期之后的會話日期。
會議日期示例:2/3/22、2/10/22、2/17/22
具有所需輸出的示例評估日期:2/3/22(應該匹配 2/3/22)、2/4/22(應該匹配 2/3/22)、2/11/22(應該匹配 2/10/22 )
uj5u.com熱心網友回復:
這是一種方法。
在sessions資料框中,將date列設定為索引:
sessions = sessions.set_index('date')
按索引(即按日期)對會話進行排序:
sessions = sessions.loc[sessions.index.sort_values()]
在評估中添加一session_evaluated列,其中將包含評估適用的會話日期。我們通過首先呼叫引數設定為“pad”的評估列來計算這一點,sessions.index.get_indexer()因此date我們method在不匹配的日期上“向下取整”,然后在會話索引(包含會話)中查找這些整數索引值日期):
evaluations['session_evaluated'] = pd.Series([sessions.index.to_list()[i]
for i in sessions.index.get_indexer(evaluations['date'], method='pad')])
以下是與示例輸入放在一起的樣子:
import pandas as pd
sessions = pd.DataFrame({
'date' : ['2022-02-01', '2022-03-01', '2022-04-01', '2022-05-01', '2022-01-01'],
'topic' : ['Easy 1', 'Easy 2', 'Intermediate', 'Advanced', 'Intro']
})
evaluations = pd.DataFrame({
'date' : [
'2022-01-05', '2022-01-10', '2022-01-15', '2022-01-20', '2022-01-25',
'2022-02-01', '2022-02-05', '2022-02-28',
'2022-03-01', '2022-03-15', '2022-03-31',
'2022-04-01', '2022-04-15'
],
'rating' : [9,8,7,8,9,5,4,3,10,10,10,2,4]
})
sessions['date'] = pd.to_datetime(sessions['date'])
evaluations['date'] = pd.to_datetime(evaluations['date'])
sessions = sessions.set_index('date')
sessions = sessions.loc[sessions.index.sort_values()]
print(sessions)
print(evaluations)
evaluations['session_evaluated'] = pd.Series([sessions.index.to_list()[i]
for i in sessions.index.get_indexer(evaluations['date'], method='pad')])
print(evaluations)
結果:
topic
date
2022-01-01 Intro
2022-02-01 Easy 1
2022-03-01 Easy 2
2022-04-01 Intermediate
2022-05-01 Advanced
date rating
0 2022-01-05 9
1 2022-01-10 8
2 2022-01-15 7
3 2022-01-20 8
4 2022-01-25 9
5 2022-02-01 5
6 2022-02-05 4
7 2022-02-28 3
8 2022-03-01 10
9 2022-03-15 10
10 2022-03-31 10
11 2022-04-01 2
12 2022-04-15 4
date rating session_evaluated
0 2022-01-05 9 2022-01-01
1 2022-01-10 8 2022-01-01
2 2022-01-15 7 2022-01-01
3 2022-01-20 8 2022-01-01
4 2022-01-25 9 2022-01-01
5 2022-02-01 5 2022-02-01
6 2022-02-05 4 2022-02-01
7 2022-02-28 3 2022-02-01
8 2022-03-01 10 2022-03-01
9 2022-03-15 10 2022-03-01
10 2022-03-31 10 2022-03-01
11 2022-04-01 2 2022-04-01
12 2022-04-15 4 2022-04-01
更新:
這是使用該merge_asof()功能的另一種方法。它不需要日期列作為索引(盡管它確實要求兩個資料框引數都按 排序date):
sessions['date'] = pd.to_datetime(sessions['date'])
evaluations['date'] = pd.to_datetime(evaluations['date'])
evaluations = pd.merge_asof(
evaluations.sort_values(by=['date']),
sessions.sort_values(by=['date'])['date'].to_frame().assign(session_evaluated=sessions['date']),
on='date')
print(evaluations)
輸出:
date rating session_evaluated
0 2022-01-05 9 2022-01-01
1 2022-01-10 8 2022-01-01
2 2022-01-15 7 2022-01-01
3 2022-01-20 8 2022-01-01
4 2022-01-25 9 2022-01-01
5 2022-02-01 5 2022-02-01
6 2022-02-05 4 2022-02-01
7 2022-02-28 3 2022-02-01
8 2022-03-01 10 2022-03-01
9 2022-03-15 10 2022-03-01
10 2022-03-31 10 2022-03-01
11 2022-04-01 2 2022-04-01
12 2022-04-15 4 2022-04-01
更新#2:上面代碼中
的呼叫assign()也可以使用**kwargs語法撰寫,以防我們想使用帶空格的列名,或者不是有效的python識別符號(而不是session_evaluated)。例如:
evaluations = pd.merge_asof(
evaluations.sort_values(by=['date']),
sessions.sort_values(by=['date'])['date'].to_frame()
.assign(**{'Evaluated Session (Date)' : lambda x: sessions['date']}),
on='date')
輸出:
date rating Evaluated Session (Date)
0 2022-01-05 9 2022-01-01
1 2022-01-10 8 2022-01-01
2 2022-01-15 7 2022-01-01
3 2022-01-20 8 2022-01-01
4 2022-01-25 9 2022-01-01
5 2022-02-01 5 2022-02-01
6 2022-02-05 4 2022-02-01
7 2022-02-28 3 2022-02-01
8 2022-03-01 10 2022-03-01
9 2022-03-15 10 2022-03-01
10 2022-03-31 10 2022-03-01
11 2022-04-01 2 2022-04-01
12 2022-04-15 4 2022-04-01
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/461648.html
下一篇:在R中迭代時,日期被轉換為數字
