我有一個包含以下列的資料框:用戶 ID、參考日期、事件日期、事件值。
- 用戶 ID 是唯一的,每個 ID 有多個條目
- 每個用戶 ID 的參考日期都是唯一的
我想找到最接近參考日期的事件的索引,包括之前和之后。
例子:
| 用戶身份 | 參考日期 | 活動日期 | 事件值 |
|---|---|---|---|
| 1234 | 2021-05-15 | 2020-09-02 | 10 |
| 1234 | 2021-05-15 | 2021-04-28 | 15 |
| 1234 | 2021-05-15 | 2021-06-01 | 11 |
代碼應該回傳類似
| 用戶身份 | 參考日期 | 事件_1 | 值_1 | 事件_2 | 值_2 |
|---|---|---|---|---|---|
| 1234 | 2021-05-15 | 2021-04-28 | 15 | 2021-06-01 | 11 |
uj5u.com熱心網友回復:
您可以merge_asof在將direction引數設定為 的同時使用陳述句輕松完成此操作nearest,如下所示:
df_merged = pd.merge_asof(df1, df2, on=['user_id'], direction='nearest')
在此之前,請確保您的日期采用日期格式:
df['reference_date'] = pd.to_datetime(df['reference_date'])
df['event_date'] = pd.to_datetime(df['event_date'])
因此,要在背景關系中將其作為一個整體,代碼應如下所示:
import pandas as pd
my_dict = {'user_id':[1234, 1234, 1234], \
'reference_date':['2021-05-15', '2021-05-15', '2021-05-15'], \
'event_date':['2020-09-02', '2021-04-28', '2021-06-01'], \
'event_value':[10, 15, 11]}
df = pd.DataFrame(my_dict)
df['reference_date'] = pd.to_datetime(df['reference_date'])
df['event_date'] = pd.to_datetime(df['event_date'])
df1 = df[['user_id','reference_date']]
df2 = df[['user_id','reference_date','event_date','event_value']]
df_merged = pd.merge_asof(df1, df2, on=['user_id'], direction='nearest')
df_merged = df_merged.drop_duplicates(subset=['user_id'])
print(df_merged)
uj5u.com熱心網友回復:
import pandas as pd
from io import StringIO
# Sample data but added an additonal group
s = """user_id,reference_date,event_date,event_value
1234,2021-05-15,2020-09-02,10
1234,2021-05-15,2021-04-28,15
1234,2021-05-15,2021-06-01,11
12346,2021-05-20,2021-09-02,10
12346,2021-05-20,2021-06-28,15
12346,2021-05-20,2021-06-01,11"""
df = pd.read_csv(StringIO(s))
# convert dates to datetime
df['reference_date'] = pd.to_datetime(df['reference_date'])
df['event_date'] = pd.to_datetime(df['event_date'])
# Filter your df using loc
# Calculate the difference between the reference and event date
# groupby and get the index of the min values using idxmin
df.loc[df.assign(diff=abs(df[['reference_date',
'event_date']].diff(axis=1)['event_date']))\
.groupby(['user_id', 'reference_date'])['diff'].idxmin()]
user_id reference_date event_date event_value
1 1234 2021-05-15 2021-04-28 15
5 12346 2021-05-20 2021-06-01 11
如果你想保留所有的最小值,而不僅僅是第一次出現,那么使用 groupby 和 transform
d = df.assign(diff=abs(df[['reference_date', 'event_date']].diff(axis=1)['event_date']))
df[d['diff'] == d.groupby(['user_id', 'reference_date'])['diff'].transform(min)]
user_id reference_date event_date event_value
1 1234 2021-05-15 2021-04-28 15
2 1234 2021-05-15 2021-06-01 11
5 12346 2021-05-20 2021-06-01 11
uj5u.com熱心網友回復:
def fcl(df, dtObj):
return df.iloc[np.argmin(np.abs(df.index.to_pydatetime() - dtObj))]
ArgMin找到 f 主題的全域最小值。
所以這只是回傳一個元素,它具有兩個日期之間的最小差異。
此函式回傳 df 中最近的日期,其中dtObj - 是該日期。
用于您的情況:
def fcl(df, columnName, dtObj):
return df.iloc[np.argmin(np.abs(df[columnName] - dtObj))]
date = "2021-02-15"
date = pd.to_datetime(date)
test = fcl(df,'reference_date', date)
當然,dtObject 可以是 columnName 引數或 event_date - 就像這里:
def fcl(df, columnName, dtObj):
return df.iloc[np.argmin(np.abs(df[columnName] - df['event_date']))]
輸出:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/331252.html
