Python:多文件处理非常慢

Python:多文件处理非常慢,python,Python,我必须同时阅读2种不同类型的文件,以便同步它们的数据。这些文件以不同的频率并行生成 文件1的大小将非常大(>10 GB),其结构如下:数据是一个包含100个字符的字段,其后面的数字是两个文件共用的同步信号(即,两个文件中的同步信号同时改变) 文件2大小较小(最多10 MB,但数量更多),具有相同的结构,不同之处在于同步信号变化之间的行数不同: DATA 1 ... another 300-400 lines DATA 1 DATA 0 ... and so on 以下是我用来读取文件的代码:

我必须同时阅读2种不同类型的文件,以便同步它们的数据。这些文件以不同的频率并行生成

文件1的大小将非常大(>10 GB),其结构如下:数据是一个包含100个字符的字段,其后面的数字是两个文件共用的同步信号(即,两个文件中的同步信号同时改变)

文件2大小较小(最多10 MB,但数量更多),具有相同的结构,不同之处在于同步信号变化之间的行数不同:

DATA 1
... another 300-400 lines
DATA 1
DATA 0
... and so on
以下是我用来读取文件的代码:

def getSynchedChunk(fileHandler, lastSynch, end_of_file):

    line_vector = [];                         # initialize output array
    for line in fileHandler:                  # iterate over the file
        synch = int(line.split(';')[9]);      # get synch signal
        line_vector.append(line);         
        if synch != lastSynch:                # if a transition is detected
            lastSynch = synch;                # update the lastSynch variable for later use
            return (lastSynch, line_vector, True); # and exit - True = sycnh changed

     return (lastSynch, line_vector, False); # exit if end of file is reached
我必须同步数据块(具有相同同步信号值的行)并将新行写入另一个文件。 我正在使用Spyder

在测试中,我使用了较小的文件,文件1为350MB,文件2为35MB。 我还使用了内置的分析器来查看在哪里花费的时间最多,似乎46秒中有28秒用于实际读取文件中的数据。其余部分用于同步数据和写入新文件

如果我将时间扩展到以Gig为单位的文件大小,则需要几个小时才能完成处理。我将尝试改变处理的方式,使其更快,但有没有更快的方式来读取大文件


一行数据如下所示:

01/31/19 08:20:55.886;0.049107050;-0.158385641;9.457415342;-0.025256720;-0.017626805;-0.000096349;0.107;-0.112;0

这些值是传感器测量值。最后一个数字是synch值。

我不习惯Spyder,但您可以尝试使用多线程对大文件进行分块,Python有一个选项,不需要任何外部库,因此它可能也可以与Spyder一起使用。()

分块的过程:

  • 以行为单位获取文件的长度
  • 开始将列表减半,直到“不太大”
  • 为每个小块使用一个线程
  • 利润

  • 我建议先读取整个文件,然后进行处理。这有一个巨大的优势,即读取时的所有附加/连接等都是通过优化模块在内部完成的。同步可以在之后进行

    为此,我强烈建议使用,这是迄今为止处理时间序列数据(如测量)的最佳工具

    导入文件时,猜测文本文件中的
    csv
    是正确的格式,可以通过以下方法完成:

    df = pd.read_csv(
        'DATA.txt', sep=';', header=None, index_col=0, 
        parse_dates=True, infer_datetime_format=True, dayfirst=True)
    
    为了减少内存消耗,您可以指定
    chunksize
    来拆分文件读取,或者
    low_memory=True
    来内部拆分文件读取过程(假设最终数据帧适合您的内存):

    现在,您的数据将存储在一个
    数据框中
    ,它非常适合于时间序列。该索引已转换为DateTimeIndex,这将允许良好的绘图、重新采样等

    sync
    状态现在可以像在numpy数组中一样轻松访问(只需添加
    iloc
    访问方法),方法如下:

    这非常适合于使用快速矢量化的两个或多个文件的同步


    根据可用内存读取文件

    try:
        df = pd.read_csv(
            'DATA.txt', sep=';', header=None, index_col=0, 
            parse_dates=True, infer_datetime_format=True, dayfirst=True)
    except MemoryError:
        df = pd.read_csv(
            'DATA.txt', sep=';', header=None, index_col=0, 
            parse_dates=True, infer_datetime_format=True, dayfirst=True,
            low_memory=True)
    

    try/except
    解决方案可能不是一个优雅的解决方案,因为在引发MemoryError之前需要一些时间,但它是故障保护的。由于在大多数情况下
    low_memory=True
    很可能会降低文件读取性能,因此在大多数情况下
    try
    块应该更快。

    Spyder是一个IDE,通常不会影响脚本的结果。更有趣的信息是
    DATA
    的文件扩展名和文件第一行的摘录。根据您的代码,您正在加入第一行,其中synch与前几行发生了更改。这是预期的行为吗?两个文件的行是否需要交错,或者您是否可以将块连接起来?@EduardPalkoMate好的,我扩展了我的解决方案。行吗?不客气!如果它在没有
    low_memory=True
    的情况下工作,最好不要使用它。它会将读取分块进行,这将减少内存消耗,但很可能会使速度变慢。因此,只有在遇到
    内存错误时才使用
    low_memory=True
    。在接下来的几分钟里,我将在我的答案中添加一个简短的例子。我将查看它。谢谢。这太简单了。分而治之的方法只有在块的处理是非线性的情况下才有好处。它也没有考虑到线程工作负载包含不同逻辑块数据的必要性。它需要测试。有一点,线程实际上会减慢速度。这就是为什么我写得不太大。所以,不要试图把它分成很小的部分。这种方法的内存消耗情况如何?这应该适用于大于10GB的文件。我正要添加一些有关此问题的信息。:)
    df = pd.read_csv(
        'DATA.txt', sep=';', header=None, index_col=0, 
        parse_dates=True, infer_datetime_format=True, dayfirst=True,
        low_memory=True)
    
    df.iloc[:, 8]  # for all sync states
    df.iloc[0, 8]  # for the first synch state
    df.iloc[1, 8]  # for the second synch state
    
    try:
        df = pd.read_csv(
            'DATA.txt', sep=';', header=None, index_col=0, 
            parse_dates=True, infer_datetime_format=True, dayfirst=True)
    except MemoryError:
        df = pd.read_csv(
            'DATA.txt', sep=';', header=None, index_col=0, 
            parse_dates=True, infer_datetime_format=True, dayfirst=True,
            low_memory=True)