追加数据帧时如何改善嵌套for循环的运行时间(非常大)

时间:2019-07-11 19:30:03

标签: python performance dataframe for-loop iteration

我正在读取一个4维的netcdf文件,并遍历每个变量并将它们附加到pandas DataFrame。从外部到内部,每个级别的迭代次数是:40、90、144、312。在内部循环中,我将所有312个值附加到数组中,然后将该数组设置为数据帧中的相应单元格。它目前已经运行了大约1个小时,并且只经历了外循环第一次遍历的一半(我正在使用print语句来指示迭代有多远)。使用这段时间,我估计完成外循环的第一遍大约需要2个小时,并且有40个外循环,因此程序应该在80个小时后终止。这非常长,我必须对多个数据集执行整个过程!该数据集是161,740,800个值。我如何加快这个过程?有没有更有效的方法来创建数据框?

我正在这样做,以便可以对数据运行线性回归和其他ML技术。我尝试使用xarray直接读取netcdf文件,然后将其转换为dask数据框。使用这些方法访问数据时,我一直遇到问题...每次尝试执行一些操作以查看实际数据时,即使它只是一个简单的.head(1)命令,内核也会崩溃。 (我正在使用Python2.7和Spyder)。我正在尝试编写一个重新打包程序,该程序将使用netcdf文件(这对于我理解和使用它非常令人困惑),并将其变成易于处理的数据帧。我愿意再次尝试xarray或dask数据帧,但是我不确定如何在运行.head()或.tail()操作的数秒内处理内核崩溃(更不用说线性回归/随机森林了! )。请指教!数据是大气数据。

def __init__(self):

        self.data = xr.open_dataset('/Users/Desktop/Data/O3_vmr_MON_1861-1886.S1anl_1c6_1870.nc')

        self.lon = self.data.variables['lon'] # longitude
        self.lat = self.data.variables['lat'] # latitude
        self.level = self.data.variables['level'] # level/height
        self.plm = self.data.variables['plm'] 
        self.ple = self.data.variables['ple']
        self.O3 = self.data.variables['O3_vmr'] # ozone


    def loop(self):

        ozone_arr = [] # array to hold all the values at each level,lat,lon point in time
        ozone_df = [] 

        # for loop to go through all values over time
        for lev in range(0,40):
            for lat in range(0,90):
                for lon in range(0,144): 
                    for t in range(0,312):
                        ozone_arr.append(self.data.O3_vmr[t,lev,lat,lon].values)

                    ozone_df.append({'level':self.level[lev].values, 'lat':self.lat[lat].values, 'lon':self.lon[lon].values, 'O3': ozone_arr})
                    ozone_arr = [] # reset array of all values at this point in time

                print('lat', lat) # to monitor progress
            print('lev', lev) # to monitor progress

        ozone_df = pd.DataFrame(ozone_df)
        print(ozone_df.head(100))

        self.ozone_df = ozone_df     

试图记录一段时间内所有水平,纬度和经度的O3(臭氧)测量值。

1 个答案:

答案 0 :(得分:1)

首先尝试使用np.reshape将数据重塑为2维。

import numpy as np

ozone_arr = np.reshape(data, (length_of_df, num_columns))

然后插入到DataFrame中。

df = pd.DataFrame(ozone_arr)

这种方法快得多,因为您的数据形状将发生变化,而不必在内存中四处移动。

根据数据的结构方式,您可能必须对其进行切片才能使其成为所需的形状。您可能想通过一个小数组进行练习以弄清NumPy的工作原理。

最重要的是,如果速度很重要,请避免循环。

NumPy slicing documentation