1

通常我可以在这个网站上很快找到我的困境的答案,但也许这个问题需要更具体的接触;

我从泰克示波器下载了大约 5000 万长的 unicode 字符串。分配这个对于内存来说是一件痛苦的事情(sys.getsizeof() 报告 ~100 MB)

问题在于我需要将其转换为 CSV,以便我可以获取 10,000 个逗号分隔值中的 10,000 个(这是固定的)... 1)我尝试了 split(",") 方法,使用这个, python内核上的RAM使用量又增加了300 MB ....但是这个过程非常有效(除非我在一个例程中循环这个~100次......在迭代40-50之间的某个地方,内核吐出一个内存错误.) 2) 我编写了自己的脚本,在下载了这个荒谬的长字符串后,扫描逗号的数量,直到看到 10,000 并停止,将逗号之间的所有值转换为浮点数并填充一个 np 数组。从内存使用的角度来看,这非常有效(从导入文件之前到运行脚本之后,内存使用量仅变化 150MB。)但是它慢得多,

下面是用于处理这个文件的代码,如果你 PM 我,我可以给你发一份字符串的副本以供试验(但我相信生成一个可能更容易)

代码 1(使用 split() 方法)

PPStrace = PPSinst.query('CURV?')
PPStrace = PPStrace.split(',')
PPSvals = []
for iii in range(len(PPStrace)): #does some algebra to values
    PPStrace[iii] = ((float(PPStrace[iii]))-yoff)*ymult+yzero

maxes=np.empty(shape=(0,0))
iters=int(samples/1000)
for i in range(1000): #looks for max value in 10,000 sample increments, adds to "maxes"
    print i
    maxes = np.append(maxes,max(PPStrace[i*iters:(i+1)*iters]))
PPS = 100*np.std(maxes)/np.mean(maxes)
print PPS," % PPS Noise"

代码 2(自生成脚本);

PPStrace = PPSinst.query('CURV?')
walkerR=1
walkerL=0
length=len(PPStrace)
maxes=np.empty(shape=(0,0))
iters=int(samples/1000) #samples is 10 million, iters then is 10000

for i in range(1000):
    sample=[] #initialize 10k sample list
    commas=0 #commas are 0
    while commas<iters: #if the number of commas found is less than 10,000, keep adding values to sample
        while PPStrace[walkerR]!=unicode(","):#indexes commas for value extraction
            walkerR+=1
            if walkerR==length:
                break
        sample.append((float(str(PPStrace[walkerL:walkerR]))-yoff)*ymult+yzero)#add value between commas to sample list
        walkerL=walkerR+1
        walkerR+=1
        commas+=1
    maxes=np.append(maxes,max(sample))
PPS = 100*np.std(maxes)/np.mean(maxes)
print PPS,"% PPS Noise"

还尝试了带有 StringIO 的 Pandas Dataframe 进行 CSV 转换。那个东西只是试图将它读入框架时出现内存错误。

我认为解决方案是将其加载到 SQL 表中,然后将 CSV 提取到 10,000 个样本块中(这是脚本的预期目的)。但我不想这样做!

感谢您的所有帮助!

4

2 回答 2

0

你试过类cStringIO吗?它就像文件 IO,但使用字符串作为缓冲区而不是指定文件。坦率地说,我希望您患有慢性速度问题。您自己生成的脚本应该是正确的方法。如果您一次读取一个块,然后在读取下一个块时解析它,您可能会得到一些加速。


对于并行处理,请使用multiprocessing包。有关详细信息和示例,请参阅官方文档本教程

简而言之,您创建了一个函数来体现您想要并行运行的过程。然后,您创建一个以该函数作为目标参数的进程。然后开始这个过程。当您想将其线程合并回主程序时,请使用join

于 2016-01-27T22:50:13.790 回答
0

看看 numpy.frombuffer ( http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.frombuffer.html )。这使您可以指定计数和偏移量。您应该能够将大字符串放入缓冲区,然后分块处理它以避免巨大的内存峰值。


编辑 2016-02-01

由于 frombuffer 需要具有固定的字节宽度,我尝试了 numpy.fromregex ,它似乎能够快速解析字符串。它必须完成整个事情,但这可能会导致一些内存问题。http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.fromregex.html

像这样的东西:

buf = StringIO.StringIO(big_string)
output = numpy.fromregex(buf, r'(-?\d+),', dtype=[('val', np.int64)])
# output['val'] is the array of values
于 2016-01-27T18:28:36.360 回答