内存有效的方法,使更改CSV文件和合并成一个大的CSV结果使用Pandas?

2024-05-19 05:53:21 发布

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

我有很多日志文件,结构如下所示:

logs | -- machine1 | | | -- day1 | | | | | -- machine1_timestamp11.log | | -- machine1_timestamp12.log | | | -- day2 | | | | | -- machine1_timestamp21.log | -- machine2 | | | -- day1 | | | . . .

日志文件跟踪机器的状态,并且在两个连续的日志文件中可能存在感兴趣的信息

我的最终目标是合并给定日期的所有日志文件,然后再次拆分它们。我只有时间连续数据的日志文件,其中计算机的状态是感兴趣的。每个日志文件根据日志记录开始的时间命名,CSV中有一个timeOffset列。因此,我希望将timeOffset + timestamp添加到一个新列中,并使用此列跟踪合并文件中哪个条目的位置

给定一个CSV,我已经知道如何将它分割成“有趣的部分”,但是由于数据量大(通常为5gb/天),我无法让合并工作

在我看来,有四种选择:

  1. 获得更多的内存
  2. 利用一些巧妙的数据流来避免将所有日志文件读入内存
  3. 对日志文件进行预处理,以便过滤过程已经进行。尽管如此,我仍然认为这些生成的日志文件会太大
  4. 读取日志文件,添加必要的数据,将其作为新的CSV文件写入磁盘。然后——对于所有剩余的日志文件——读取另一个日志文件,添加必要的数据,将其附加到CSV

下面的代码实现了这个技巧(我认为),但是我在运行它的大部分时间里内存都用完了

def main():

    # Acquire list of all log files
    files = glob.glob(root + 'logs/day1/*.log', recursive = True)

    # Create a dataframe for each file
    dfs = list()
    for path in files:

        # Extract machine ID and time stamp from filename
        file_name = path.split("/")[-1]
        machine = file_name.split("_")[0]
        unix_ms_time = datetime.fromtimestamp(int(file_name.split("_")[-1].split(".")[0])/1000.0)
        date = unix_ms_time.strftime("%Y-%m-%d")

        # Read data from file
        df = pd.read_csv(path, sep = ';')

        # Add a time column to allow for continuity between files
        df["time"] = unix_ms_time + pd.to_timedelta(df["timeOffset"], unit = "ms")

        # Add each dataframe to list
        dfs.append(df)

    # Concatenate all frames, the resulting frames contains all log data for
    # one particular day and machine
    result = pd.concat(dfs)

    # Write result to disk
    root_save = "merged/"
    save_path = "{}{}_{}.csv".format(root_save, machine, date)
    print("Saving to: {}".format(save_path))
    result.to_csv(save_path)

替代“购买更多的RAM”是不可能的,但我想就如何继续与替代一些投入


Tags: 文件csvtopathlogdffortime

热门问题