【发布时间】:2021-08-23 15:09:20
【问题描述】:
我在使用日期时间索引移动大型数据框时遇到了运行时间问题。
使用创建的虚拟数据的示例:
df = pd.DataFrame({'col1':[0,1,2,3,4,5,6,7,8,9,10,11,12,13]*10**5,'col3':list(np.random.randint(0,100000,14*10**5)),'col2':list(pd.date_range('2020-01-01','2020-08-01',freq='M'))*2*10**5})
df.col3=df.col3.astype(str)
df.drop_duplicates(subset=['col3','col2'],keep='first',inplace=True)
如果我不使用 datetimeindex 换档,只需要大约 12 秒:
%%time
tmp=df.groupby('col3')['col1'].shift(2,fill_value=0)
Wall time: 12.5 s
但是当我使用 datetimeindex 时,作为我需要的那种情况,大约需要 40 分钟:
%%time
tmp=df.set_index('col2').groupby('col3')['col1'].shift(2,freq='M',fill_value=0)
Wall time: 40min 25s
在我的情况下,我需要从 shift(1) 到 shift(6) 的数据,并将它们与 col2 和 col3 的原始数据合并。所以我使用for 循环和合并。
有什么解决办法吗?感谢您的回答,非常感谢您的回复。
Ben 的回答解决了这个问题:
%%time
tmp=df1[['col1','col3', 'col2']].assign(col2 = lambda x: x['col2'] + MonthEnd(2)).set_index(['col3', 'col2']).add_suffix(f'_{2}').fillna(0).reindex(pd.MultiIndex.from_frame(df1[['col3','col2']])).reset_index()
Wall time: 5.94 s
也实现了循环:
%%time
res=(pd.concat([df1.assign(col2 = lambda x: x['col2'] + MonthEnd(i)).set_index(['col3', 'col2']).add_suffix(f'_{i}') for i in range(0,7)],axis=1).fillna(0)).reindex(pd.MultiIndex.from_frame(df1[['col3','col2']])).reset_index()
Wall time: 1min 44s
实际上,我的真实数据已经在使用MonthEnd(0),所以我只是在range(1,7) 中使用循环。我还实现了多列,所以我不使用astype,并实现reindex,因为我使用left merge。
【问题讨论】:
标签: python-3.x pandas dataframe shift datetimeindex