Python:多个文件处理非常慢

时间:2019-02-07 10:07:40

标签: python

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

文件1(其大小非常大(> 10 GB))具有以下结构: DATA 是一个包含100个字符的字段,其后的数字是一个同步信号,它是这两个文件常见(即,两个文件中它们同时更改)。

DATA 1
DATA 1
... another 4000 lines
DATA 1
DATA 0
... another 4000 lines and so on

文件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使用350 MB,文件2使用35 MB。 我还使用内置的探查器查看了花费最多的时间,似乎46秒中的28秒实际上是在从文件中读取数据。其余的用于同步数据并写入新文件。

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


一行数据如下:

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

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

2 个答案:

答案 0 :(得分:1)

我不习惯Spyder,但是您可以尝试使用多线程对大文件进行分块,Python为此提供了一个选项,而无需任何外部库,因此它也可能与Spyder一起使用。 (https://docs.python.org/3/library/threading.html

分块的过程:

  1. 以行为单位获取文件的长度
  2. 开始将列表切成两半,直到其“不太大”为止
  3. 为每个小块使用一个线程。
  4. 利润

答案 1 :(得分:1)

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

为此,我强烈推荐,使用pandas,它是迄今为止处理诸如测量之类的时间序列数据的最佳工具。

导入文件,猜测文本文件中的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来内部拆分文件读取过程(假设最终数据帧适合您的内存):< / p>

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

现在,您的数据将存储在DataFrame中,非常适合时间序列。索引已经转换为DateTimeIndex,可以进行漂亮的绘图,重采样等。

现在可以像使用numpy数组一样轻松访问sync状态(只需添加iloc访问方法)即可:

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)

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