我有一个CSV文件,我想修改里面的值。此文件超过100万行。
在文件开始时,脚本以5000 lines per seconds
的速度运行,但随后它减少到400 lines per seconds
。
我想知道为什么它是慢下来,以及如何提高这个脚本的性能?
txt = ""
data = open(path + "_mag.csv").readlines()
i = 0
for line in tqdm.tqdm(data):
if i == 0:
txt += line + "\n"
i += 1
continue
values = line.split(";")
for j, value in enumerate(mag_rotated[i-1]): # 15 values in float type
index = j + 5
values[index] = str(value)
new_line = ";".join(values)
txt += new_line + "\n"
i += 1
下面是一个小数据行的例子:
Timestamp [µs];Temp ADC1 [°C];Temp ADC2 [°C];Temp ADC3 [°C];Temp ADC4 [°C];X0 [µT];Y0 [µT];Z0 [µT];X1 [µT];Y1 [µT];Z1 [µT];X2 [µT];Y2 [µT];Z2 [µT];X3 [µT];Y3 [µT];Z3 [µT];X4 [µT];Y4 [µT];Z4 [µT];unused;X5 [µT];Y5 [µT];Z5 [µT];X6 [µT];Y6 [µT];Z6 [µT];X7 [µT];Y7 [µT];Z7 [µT];X8 [µT];Y8 [µT];Z8 [µT];X9 [µT];Y9 [µT];Z9 [µT];unused
911532093;30.563;30.313;;;-1.62919885e+01;1.86305991e+01;3.93283914e+01;-1.59370440e+01;1.88661384e+01;3.93722822e+01;-1.60104993e+01;1.89392587e+01;3.93954596e+01;-1.63657738e+01;1.86798405e+01;3.93386700e+01;-1.65630085e+01;1.78254986e+01;3.95608333e+01;;;;;;;;;;;;;;;;;
911533093;30.563;30.313;;;-1.62927678e+01;1.86261966e+01;3.93056706e+01;-1.59385424e+01;1.88634411e+01;3.93504949e+01;-1.60110385e+01;1.89362330e+01;3.93737558e+01;-1.63657738e+01;1.86764223e+01;3.93170219e+01;-1.65643876e+01;1.78232520e+01;3.95398268e+01;;;;;;;;;;;;;;;;;
911534093;30.563;30.313;;;-1.62899203e+01;1.86278438e+01;3.93394221e+01;-1.59340472e+01;1.88623921e+01;3.93840899e+01;-1.60095108e+01;1.89366524e+01;3.94075406e+01;-1.63627492e+01;1.86763323e+01;3.93510360e+01;-1.65617493e+01;1.78224132e+01;3.95712317e+01;;;;;;;;;;;;;;;;;
有关上下文:我的脚本旨在替换这15个值:X0 [µT] Y0 [µT] Z0 [µT] X1 [µT] Y1 [µT] Z1 [µT] X2 [µT] Y2 [µT] Z2 [µT] X3 [µT] Y3 [µT] Z3 [µT] X4 [µT] Y4 [µT] Z4 [µT]
2条答案
按热度按时间uwopmtnx1#
我想有两个原因导致了速度的下降。
1.是因为您试图将所有修改的数据存储到单个字符串变量
txt
中。1.您使用
readlines()
将整个CSV文件一次性读入内存,由于文件很大,这会消耗大量内存。您应该直接写入输出文件,而不是将其全部存储在内存中。
一个很好的方法是打开两个文件,输入和输出文件。然后从输入文件中一次读取一行,并将修改后的行直接写入输出文件
vawmfj5a2#
就像Obaskly在第2条中指出的那样,在一百万次迭代中附加字符串是灾难性的慢。
在我的机器上,开始大约5000它/秒,并稳步下降。
既然你标记了python和csv,我建议使用Python的标准csv模块:它只比手动解析稍微慢一点(在我的机器上,读/写1 M+行需要4秒,比1秒),并且使代码更简单:
因为我用
next(reader)
手动迭代了header,所以当我开始枚举for循环中的行时,它自然会从i = 0
开始,我相信它会与mag_rotated完美匹配;没有更多[i - 1]
。此外,由于您知道只需要更改从字段5开始的15个字段,因此可以使用Python的切片表示法row[5:20] = mag_rotated[i]
来更新这些字段;不再迭代带偏移量的字段。如果你想使用manualally-parse-CSV路径,你可以使用上面的一些技巧来清理你已经拥有的代码: