簡體   English   中英

向量化 function 以從日期列表中獲取最接近的日期

[英]Vectorize a function to get closest date from a list of dates

我不能使用 pandas 或 numpy 以外的外部庫

如果我有一個 dataframe 之類的

import pandas as pd d = pd.DataFrame({'purchase_date':[datetime(2022,1,5),datetime(2022,12,10)],'shop_visits':[[datetime(2021,1,4),datetime(2022,1,6),datetime(2022,1,7)],[datetime(2022,5,30),datetime(2022,9,30),datetime(2022,12,10)]]})
購買_dt shop_visits
2022-01-05 [2022-01-04,2022-01-06,2022-01-07]
2022-12-10 [2022-05-30,2022-09-30,2022-12-10]

我需要一個 function,第一行返回 2022-01-06,第二行返回 2022-12-10,因為兩者都是在 purchase_dt 之后列表中最接近的日期。

我有一個 function 和 apply 已經用我自己的 lambda 密鑰完成了最小值,但它花費的時間太長,我想矢量化:

 d.apply(lambda x: min([d for d in x['shop_visits'] if d >= x['purchase_date']],key=lambda d: dx['purchase_date']),axis=1)

問題是我不確定這是否可以使用 numpy 來完成。

這是實現它的一種方法

展開商店訪問,創建一個 df2,其中 purchase_date 等於或小於 shop_visit。 最后做一個groupby來選擇第一個結果

df2=df.explode('shop_visits') df2=df2[df2['purchase_date']<=df2['shop_visits']] df2[df2.groupby(['purchase_date']).cumcount().eq(0)]

或者

df2=df.explode('shop_visits') df2[df2['purchase_date']<=df2['shop_visits']].groupby('purchase_date').first().reset_index()
 purchase_date shop_visits 0 2022-01-05 2022-01-06 1 2022-12-10 2022-12-10

您可以嘗試merge_asof

 left = d.drop(columns=["shop_visits"]).reset_index() right = d["shop_visits"].explode().sort_values().to_frame().reset_index() pd.merge_asof( left, right, by="index", left_on="purchase_date", right_on="shop_visits", direction="forward", ).drop(columns=["index"])

這是一個沒有merge_asof的更快版本:

 tmp = ( # Extract purchase_date and shop_visits d[["purchase_date", "shop_visits"]] # Explode shop_visits.explode("shop_visits") # Reset index so we can align using this index later.reset_index() # Since we only care about visits on or after the purchase_date, # filter out the rest.query("purchase_date <= shop_visits") # Sort by the original index and shop visit date.sort_values(["index", "shop_visits"]) # For each index, keep only the first visit.drop_duplicates("index") ) # Set the original index back on tmp and so that we can # easily align it with the original dataframe d["first_visit_after_purchase"] = tmp.set_index("index")[["shop_visits"]] # Note that some first_visit_after_purchase may be NaN due # to our query condition

d有 1M 行和每行 10 次訪問時,在我的古老 Mac 上花了 7 秒。

處理時間隨着商店訪問的總數線性增長( len(d["shop_visits"].explode()) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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