【发布时间】:2021-02-12 03:06:59
【问题描述】:
感谢社区对此提供的任何帮助。我已经玩了几天了。
我有 2 个数据框,df1 和 df2。第一个数据帧将始终是大约 20-3 万行的 1 分钟数据。第二个数据帧将包含随机时间以及相关的相关数据,并且总是相对较小(1000-4000 行 x 4 或 5 列)。我正在使用 itertuples 处理 df1 以执行特定时间的切片(尾随)。这个过程重复了数千次,并且下面的单条切片线 (df3 = df2...) 导致了超过 50% 的运行时间。只需在下面的单行中添加几个切片标准,就可以使运行数小时的最终运行时间增加 30% 以上!
我考虑过尝试 pandas 的“查询”,但读过它真的只对更大的数据帧有帮助。我的想法是将 df2 减少为一个 numpy 数组、简单的 python 列表或其他可能会更好,因为它总是相当短,尽管我认为我需要将它放回数据框以进行后续排序、求和和向量乘法之后出现在主要代码中。我确实成功地在 12 核设置上利用了并发期货,这为我的整个应用程序提高了大约 5 倍的速度,尽管我仍在谈论运行时间。
任何帮助或建议将不胜感激。 说明问题的示例代码:
import pandas as pd
import numpy as np
import random
from datetime import datetime as dt
from datetime import timedelta, timezone
def random_dates(start, end, n=10):
start_u = start.value//10**9
end_u = end.value//10**9
return pd.to_datetime(np.random.randint(start_u, end_u, n), unit='s')
dfsize = 34000
df1 = pd.DataFrame({'datetime': pd.date_range('2010-01-01', periods=dfsize, freq='1min'), 'val':np.random.uniform(10, 100, size=dfsize)})
sizedf = 3000
start = pd.to_datetime('2010-01-01')
end = pd.to_datetime('2010-01-24')
test_list = [5, 30]
df2 = pd.DataFrame({'datetime':random_dates(start,end, sizedf), 'a':np.random.uniform(10, 100, size=sizedf), 'b':np.random.choice(test_list, sizedf), 'c':np.random.uniform(10, 100, size=sizedf), 'd':np.random.uniform(10, 100, size=sizedf), 'e':np.random.uniform(10, 100, size=sizedf)})
df2.set_index('datetime', inplace=True)
daysback5 = 3
daysback30 = 8
#%%timeit -r1 #time this section here:
#Slow portion here - Performing ~4000+ slices on a dataframe (df2) which is ~1000 to 3000 rows -- Some slowdown due to itertuples, which don't think is avoidable
for line, row in enumerate(df1.itertuples(index=False), 0):
if row.datetime.minute % 5 ==0:
#Lion's share of the slowdown:
df3 = df2[(df2['a']<=row.val*1.25) & (df2['a']>=row.val*.75) & (df2.index<=row.datetime) & (((df2.index>=row.datetime-timedelta(days=daysback30)) & (df2['b']==30)) | ((df2.index>=row.datetime-timedelta(days=daysback5)) & (df2['b']==5))) ].reset_index(drop=True).copy()
慢部分时间:
每个循环 8.53 s ± 0 ns(平均值 ± 标准偏差,1 次运行,每个循环 1 个)
df1:
datetime val
0 2010-01-01 00:00:00 58.990147
1 2010-01-01 00:01:00 27.457308
2 2010-01-01 00:02:00 20.657251
3 2010-01-01 00:03:00 36.416561
4 2010-01-01 00:04:00 71.398897
... ... ...
33995 2010-01-24 14:35:00 77.763085
33996 2010-01-24 14:36:00 21.151239
33997 2010-01-24 14:37:00 83.741844
33998 2010-01-24 14:38:00 93.370216
33999 2010-01-24 14:39:00 99.720858
34000 rows × 2 columns
df2:
a b c d e
datetime
2010-01-03 23:38:13 22.363251 30 81.158073 21.806457 11.116421
2010-01-09 16:27:32 78.952070 5 27.045279 29.471537 29.559228
2010-01-13 04:49:57 85.985935 30 79.206437 29.711683 74.454446
2010-01-07 22:29:22 36.009752 30 43.072552 77.646257 57.208626
2010-01-15 09:33:02 13.653679 5 87.987849 37.433810 53.768334
... ... ... ... ... ...
2010-01-12 07:36:42 30.328512 5 81.281791 14.046032 38.288534
2010-01-08 20:26:31 80.911904 30 32.524414 80.571806 26.234552
2010-01-14 08:32:01 12.198825 5 94.270709 27.255914 87.054685
2010-01-06 03:25:09 82.591519 5 91.160917 79.042083 17.831732
2010-01-07 14:32:47 38.337405 30 10.619032 32.557640 87.890791
3000 rows × 5 columns
【问题讨论】:
-
您是如何让您的代码在 8.5 秒内运行的?它拒绝在我的系统上几分钟内运行。
-
??它只是在 VS Code 的 Jupyter Notebook 中。这是一台非常新的计算机,配备 AMD Ryzen 9 3900。Anaconda 环境 Python 3.7.8。我看过一些帖子说一些 Pandas 函数 w 较新的 Python 版本启用了多线程??
标签: python pandas numpy dataframe