python - 附加数据帧(非常大)时如何提高嵌套 for 循环的运行时间

标签 python performance dataframe for-loop iteration

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

我这样做是为了可以对数据运行线性回归和其他机器学习技术。我尝试使用 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(臭氧)测量值。

最佳答案

首先尝试使用 np.reshape 将数据 reshape 为二维.

import numpy as np

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

然后插入到 DataFrame 中。

df = pd.DataFrame(ozone_arr)

这种方法要快得多,因为您的数据形状会发生变化,而无需在内存中移动。

根据数据的结构方式,您可能必须对其进行切片才能将其转换为您需要的形状。您可能需要使用一个小数组进行练习,以了解 NumPy 的工作原理。

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

NumPy slicing documentation

关于python - 附加数据帧(非常大)时如何提高嵌套 for 循环的运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56996116/

相关文章:

r - 将 R 公式与 dplyr 结合使用

r - 从该数据帧中的每个记录时间戳计算一秒窗口中出现多少数据帧记录时间戳的优化

python - jinja2.exceptions.UndefinedError: 'response'未定义

Python/Pygame - 如何将不同的透明度传输到不可见的表面上

python - Windows 10 上 venv 中的 pip : 'Fatal error in launcher: Unable to create process using ' "c:\users\. 。 Flask教程中遇到."'

bash - 为什么 `find -depth 1` 列出目录这么慢?

ruby - 将哈希数组转换为哈希哈希,由哈希的属性索引

c# - 字符串列表到一个字符串

python - 从 Pandas Dataframe 中每个 Id 的第一个时间戳中减去最后一个时间戳

python - 如何有条件地将一列填充到列表中另一列中的值?