纽比。在哪里在pandas datafram中性能较慢(2.5小时)

2024-09-27 00:22:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力改进大熊猫逐行每日水平衡模型的性能。输入数据集在每天的时间步长上跨越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”函数中的表达式。在

这是我在第二天逐行迭代中尝试的:

  1. Iterrows而不是nextday函数,但这不会获得任何性能

    对于索引,d.iterrows()中的行:

  2. 对于zip中的行(d.values):

这就是我试图在nextday循环中加快速度的方法:

  1. 在np.哪里表达式代替原始if/then逻辑。对于整个数据集来说,这无疑更快,但仍然很慢。在
  2. 数学函数(np.乘法, np.添加)代替python算法-这实际上只是稍微有点帮助,但它不能应用于所有的计算中,并且我得到了一些错误。我认为这是由于某些情况下常量、序列和数据帧的形状不兼容造成的。在

我的问题和/或我在SO上读到的东西,但我不清楚如何申请:

  1. 把我的逻辑表达式转换成numpy而不是pandas-我想我已经用过了np.哪里但我不清楚我还能做些什么。如果你不需要熊猫的便利,人们会说这是一个很好的绩效改进来源。我能不能在numpy中做点像.shift()之类的东西?在
  2. cython-不确定这是否真的有帮助,因为我的计算逐行性质
  3. 麻木
  4. 视图与副本-我知道这会有所不同,但不知道如何区分使用np.哪里表达式

如有任何反馈,我们将不胜感激。在


Tags: 数据numpyshifttime表达式np逻辑rows
1条回答
网友
1楼 · 发布于 2024-09-27 00:22:21

在没有预期输出的情况下解包有点困难,但是您的函数已经被矢量化了。e、 g.当你有一个d['ET_WL']-d['infilP'],它减去^{中的所有行,所以没有任何理由通过apply调用它。本质上,你所做的是:

for _ in range(len(df.columns)):
    nextday(None)

所以假设函数中的逻辑表达了你想要做的,你可以这样重写,这样它就是数据的函数:

^{pr2}$

然后你会说:

new_d = nextday(d)

如果您的函数实际上是递归的(看起来不像,只是依赖于以前的值“newsoilwatersoilwP”、“maxP”等等?)那么numba可以是一个简单的解决方案-本质上写一个函数的形式:

@numba.jit
def myfunc(a,b):
    out = np.zeros_like(a)
    for i in range(len(a)):
        if i == 0:
            out[i] = #starting value logic...
        else:
            out[i] = out[i-1] # recursive logic...
    return out

myfunc(df['a'].values, df['b'].values)

相关问题 更多 >

    热门问题