循环遍历大量文件并保存数据图的最快/最有效方法是什么?

1 投票
3 回答
3145 浏览
提问于 2025-04-18 06:02

我有一个程序,它在处理大约2000个数据文件,进行傅里叶变换,绘制变换图,然后保存这个图。感觉程序运行的时间越长,速度似乎越慢。有没有什么简单的办法可以让下面的代码运行得更快或者更干净呢?

之前,我把傅里叶变换定义成了一个函数,但我在这里看到有人说Python调用函数的开销很大,所以我就把函数去掉了,直接运行了。另外,我还听说clf()会记录之前的图形,这个记录会越来越大,导致处理速度变慢,所以我把它改成了close()。这样改动是否也不错呢?

from numpy import *
from pylab import *

for filename in filelist:

    t,f = loadtxt(filename, unpack=True)

    dt = t[1]-t[0]
    fou = absolute(fft.fft(f))
    frq = absolute(fft.fftfreq(len(t),dt))

    ymax = median(fou)*30

    figure(figsize=(15,7))
    plot(frq,fou,'k')

    xlim(0,400)
    ylim(0,ymax)

    iname = filename.replace('.dat','.png')
    savefig(iname,dpi=80)
    close()

3 个回答

0

我在ipython中测试了一些跟你做的类似的东西,发现当一个文件夹里有很多文件时,循环的速度明显变慢了。看起来这个文件夹的文件系统在处理文件数量时会有一些额外的负担,可能是和查找文件的时间有关:

loadtxt(filename, unpack = true)

你可以尝试把保存图表的地方分开,把你的文件列表分成小块,然后每一块保存到不同的文件夹里。

1

是的,添加关闭命令是个不错的主意。这应该能帮助解决你遇到的内存泄漏问题。我还建议把图形、绘图和关闭的命令放到循环外面去,只需要更新通过绘图创建的Line2D实例就可以了。想了解更多信息,可以看看这个链接

注意:我觉得这样做应该没问题,但我在这里没有测试过。

4

你有没有考虑过使用 multiprocessing 模块来让处理文件的过程并行化?假设你这里的瓶颈是 CPU 的使用(也就是说,主要耗时在傅里叶变换上,而不是读取或写入文件),这样可以加快执行速度,而不需要实际加快循环的速度。

补充:

比如,像这样做(虽然没有测试过,但应该能让你明白这个思路):

def do_transformation(filename)
    t,f = loadtxt(filename, unpack=True)

    dt = t[1]-t[0]
    fou = absolute(fft.fft(f))
    frq = absolute(fft.fftfreq(len(t),dt))

    ymax = median(fou)*30

    figure(figsize=(15,7))
    plot(frq,fou,'k')

    xlim(0,400)
    ylim(0,ymax)

    iname = filename.replace('.dat','.png')
    savefig(iname,dpi=80)
    close()

pool = multiprocessing.Pool(multiprocessing.cpu_count())
for filename in filelist:
    pool.apply_async(do_transformation, (filename,))
pool.close()
pool.join()

你可能需要调整一下在工作进程中实际完成的任务。比如,试图让磁盘输入输出部分并行化可能对你帮助不大(甚至可能会适得其反)。

撰写回答