我有这 2 个虚拟数据框
np.random.seed(12345)
df1=pd.DataFrame({'name' : ['A']*4+['B']*4,
'start_date': pd.to_datetime(['2000-03-15', '2000-06-12','2000-09-01', '2001-01-17','2000-03-19', '2000-06-14','2000-09-14', '2001-01-22']),
'end_date':pd.to_datetime(['2000-06-12','2000-09-01', '2001-01-17','2001-03-19', '2000-06-14','2000-09-14', '2001-01-22','2001-02-01'])})
date=pd.date_range('2000-01-01','2002-01-01')
name=['A']*len(date)+['B']*len(date)
date=date.append(date)
import numpy as np
low=np.random.rand(len(date))
high=low+np.random.rand(len(date))
df2=pd.DataFrame({'name': name, 'date': date, 'low':low,'high':high})
对于 df1 中的每一行,我都给出了名称、开始日期和结束日期。
我想在 high 中找到最大值,在 low 中找到与名称相同并且在 df2 中的开始日期和结束日期之间的最小值
以下是我目前的解决方案。
df1=df1.set_index('name')
df2=df2.set_index(['name','date'])
df2=df2.sort_index()
df1['max']=-1
df1['min']=-1
for name in df1.index.unique():
df=df2.loc[name]
tmphigh=[]
tmplow=[]
for (_,start_date,end_date,_,_) in df1.loc[name].itertuples(name=None):
newdf=df.iloc[df.index.searchsorted(start_date): df.index.searchsorted(end_date)]
tmphigh.append(newdf.high.max())
tmplow.append(newdf.low.min())
df1.loc[[name],['max']]=tmphigh
df1.loc[[name],['min']]=tmplow
然而,应用超过百万的行仍然需要相当长的时间。我想知道是否有更快的方法来做到这一点。
[编辑]:感谢 Pramote Kuacharoen,我能够调整他的一些代码并实现比我现有代码快 6 倍的速度。
分成循环的原因是我发现在 apply 函数中包含 df2[name] 的生成会导致计算时间显着增加。
因此我分开计算它可能有助于减少函数调用以提取 df2 中名称下的所有值。
如果有人能提出比我的方法更好的方法,我会很高兴。但这对我来说已经足够了。
以下是我目前的解决方案
from tqdm import tqdm
df1a=df1.groupby('name')
df2a=df2.groupby('name')
mergedf=df1
mergedf['maximum']=-1
mergedf['minimum']=-1
def get_min_max(row):
dfx=df2x.iloc[df2x.index.searchsorted(row['start_date']): df2x.index.searchsorted(row['end_date'])]
maximum = dfx['high'].max()
minimum = dfx['low'].min()
return pd.Series({'maximum': maximum, 'minimum': minimum})
for name,df in tqdm(df1a):
df2x=df2a.get_group(name)
mergedf.loc[[name],['maximum','minimum']]=df.apply(get_min_max,axis=1)
慕雪6442864
相关分类