我正在努力改进大熊猫逐行每日水平衡模型的性能。输入数据集在每天的时间步长上跨越33年,因此大约有12000行。我把它读入了一个数据帧'd',其中每天都是一行,所有变量都是列。这个相对较小的数据集的总运行时间约为2.5小时。在
第一天的计算为模型提供了开始/边界条件,并使用基本的python if/then逻辑应用于row1(day1),使用切片。这些第1天的计算运行速度非常快,没有问题:
d[:1].apply(newsoilwaterupperL, axis=1)
第1天数据字段示例:
^{pr2}$剩余行(2到12000行)的“下一天”计算(总共45个)是使用numpy设置的,其中表达式-我需要这些表达式提供的逻辑能力,我认为使用np.哪里允许数据帧切片“矢量化”,因此速度更快。一些但不是所有的每日变量都依赖于前一天的变量,所以我使用.shift()来捕捉前一天的值。下面是一个可以复制并运行的示例-它是根据今天早些时候发布的代码进行修订的:
import pandas as pd
import numpy as np
import time
start_time = time.time()
d = pd.DataFrame(np.random.randn(1000,12), columns=['kP', 'newsoilwatersoilwP' ,'ponddepthP' ,'soilP', \
'roWS', 'newsoilwaterP' ,'maxP' ,'PRECIP','ET_WL' ,'infilP' ,'areaP','pP'])
def nextday(row): #real code has 45 np.where calculations like these two
#Infiltration, Pond
d[1:].infilP = (24*np.multiply(d['kP'], (np.add(d['newsoilwatersoilwP'].shift(), \
d['ponddepthP'].shift())/d['soilP'])))[1:]
#Soil Water, Pond
d[1:].soilwaterP = np.where(d['roWS']+d['newsoilwaterP'].shift()+ (d['maxP'].shift() \
+d['PRECIP']-d['ET_WL']-d['infilP'])*d['areaP'] <= 0, \
#val
0.0, \
#elif
np.where(d['roWS']+d['newsoilwaterP'].shift()+(d['maxP'].shift()+d['PRECIP'] \
-d['ET_WL']-d['infilP'])*d['areaP']>= d['pP']*d['soilP']*d['areaP'], \
#val
d['pP']*d['soilP']*d['areaP'], \
#else
d['roWS']+d['newsoilwaterP'].shift()+(d['maxP'].shift()+d['PRECIP'] \
-d['ET_WL']-d['infilP'])*d['areaP']))[1:]
#ends the series of Next Day functions
d.apply(nextday, axis=0)
print "END"
print("%f seconds" % (time.time() - start_time))
我的速度问题和瓶颈似乎是接下来几天的计算(第2天到12000 x 45次计算)使用多个np.哪里“nextday”函数中的表达式。在
这是我在第二天逐行迭代中尝试的:
Iterrows而不是nextday函数,但这不会获得任何性能
对于索引,d.iterrows()中的行:
这就是我试图在nextday循环中加快速度的方法:
我的问题和/或我在SO上读到的东西,但我不清楚如何申请:
如有任何反馈,我们将不胜感激。在
在没有预期输出的情况下解包有点困难,但是您的函数已经被矢量化了。e、 g.当你有一个中的所有行,所以没有任何理由通过apply调用它。本质上,你所做的是:
d['ET_WL']-d['infilP']
,它减去^{所以假设函数中的逻辑表达了你想要做的,你可以这样重写,这样它就是数据的函数:
^{pr2}$然后你会说:
如果您的函数实际上是递归的(看起来不像,只是依赖于以前的值“newsoilwatersoilwP”、“maxP”等等?)那么
numba
可以是一个简单的解决方案-本质上写一个函数的形式:相关问题 更多 >
编程相关推荐