Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫的效率——有没有一种更快的方法来切割数千次?_Python_Pandas_Numpy_Dataframe - Fatal编程技术网

Python 熊猫的效率——有没有一种更快的方法来切割数千次?

Python 熊猫的效率——有没有一种更快的方法来切割数千次?,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,感谢社区在这方面提供的任何帮助。我已经玩了几天了 我有两个数据帧,df1和df2。第一个数据帧始终是大约2-3万行的1分钟数据。第二个数据帧将包含与相关数据相关的随机时间&总是相对较小(1000-4000行x 4或5列)。我正在使用itertuples处理df1,以便执行特定于时间的切片(拖尾)。这个过程被重复了数千次,下面的一条切片线(df3=df2…)导致了超过50%的运行时间。只需在下面的一行中添加两个切片标准,就可以使运行数小时的最终运行时增加30%+ 我曾考虑尝试熊猫的“查询”,但我读

感谢社区在这方面提供的任何帮助。我已经玩了几天了

我有两个数据帧,df1和df2。第一个数据帧始终是大约2-3万行的1分钟数据。第二个数据帧将包含与相关数据相关的随机时间&总是相对较小(1000-4000行x 4或5列)。我正在使用itertuples处理df1,以便执行特定于时间的切片(拖尾)。这个过程被重复了数千次,下面的一条切片线(df3=df2…)导致了超过50%的运行时间。只需在下面的一行中添加两个切片标准,就可以使运行数小时的最终运行时增加30%+

我曾考虑尝试熊猫的“查询”,但我读过,它只对更大的数据帧有帮助。我的想法是,最好将df2简化为numpy数组、简单python列表或其他形式,因为它总是相当短的,尽管我认为我需要将其返回到数据帧中,以便随后在主代码中进行排序、求和和和和向量乘法。我确实成功地在一个12核的设置上使用了并发futures,这使我的整个应用程序的速度提高了大约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()
df2:


实际上,交叉合并和查询对于您的数据大小非常有效:

(df1[df1.datetime.dt.minute % 5==0].assign(dummy=1)
    .merge(df2.reset_index().assign(dummy=1),
           on='dummy', suffixes=['_1','_2'])
    .query('val*1.25 >= a >= val*.75 and datetime_2 <= datetime_1 ')
    .loc[lambda x: ((x.datetime_2 >= x.datetime_1 - daysback30) & x['b'].eq(30) )
                  |((x.datetime_2>= x.datetime_1 - daysback5) & (x['b']==5))]
)

您的代码在哪里运行大约10秒

您是如何让代码在8.5秒内运行的?它拒绝在我的系统上几分钟内运行。??它就在VS Code的Jupyter笔记本中。这是一台全新的电脑,采用AMD Ryzen93900。Anaconda环境Python 3.7.8。我看到一些帖子说一些新Python版本的Pandas函数支持多线程??谢谢Quang。这很有帮助。我将不得不继续思考,在拥有这样一个完整的数据帧的情况下,我如何可能执行代码的其余部分。上面生成了一个超过一百万行的数据帧&与之相比,仅在日期上进行选择非常慢。我试着在现有的iterloop中只使用“query”部分&速度慢了18.5秒——非常像语法。向我介绍了一些新功能!!
                               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
(df1[df1.datetime.dt.minute % 5==0].assign(dummy=1)
    .merge(df2.reset_index().assign(dummy=1),
           on='dummy', suffixes=['_1','_2'])
    .query('val*1.25 >= a >= val*.75 and datetime_2 <= datetime_1 ')
    .loc[lambda x: ((x.datetime_2 >= x.datetime_1 - daysback30) & x['b'].eq(30) )
                  |((x.datetime_2>= x.datetime_1 - daysback5) & (x['b']==5))]
)
2.05 s ± 60.4 ms per loop (mean ± std. dev. of 7 runs, 3 loops each)