Python 降低计算精度以加快执行

Python 降低计算精度以加快执行,python,csv,decimal,Python,Csv,Decimal,我有一个数据采集系统,它可以测量几分钟,并生成一个包含1000万行和10列的csv文件。然后我用Python(csv.reader)导入这个csv文件,对获取的数字数据执行一系列操作(但一次“仅”10000行,否则计算机内存将被淹没)。最后,我将结果导出到另一个更小的csv文件(csv.writer)中。 问题是运行时很长,我想加快速度。当我用记事本打开原始csv文件时,我看到每个数字最多有16位数字,如0.0015800159870059、12.02577771094508等。我知道DAQ的精

我有一个数据采集系统,它可以测量几分钟,并生成一个包含1000万行和10列的csv文件。然后我用Python(csv.reader)导入这个csv文件,对获取的数字数据执行一系列操作(但一次“仅”10000行,否则计算机内存将被淹没)。最后,我将结果导出到另一个更小的csv文件(csv.writer)中。 问题是运行时很长,我想加快速度。当我用记事本打开原始csv文件时,我看到每个数字最多有16位数字,如0.0015800159870059、12.02577771094508等。我知道DAQ的精度最多为0.1%,大多数后续数字都是噪声。有没有一种优雅的方法可以迫使Python从开始到结束只使用7-8位数字进行全局操作,从而加快计算速度?我知道错误传播,我将尝试不同的位数设置,看看最佳值是多少。 请注意,对于我来说,仅使用“截断”数据(例如,包含0.0015800、12.025771等)构建临时csv文件并将其导入Python是不够的。Python中的计算也应该使用降低的精度。我研究了十进制模块,到目前为止还没有成功

with open(‘datafile’,newline='') as DAQfile:
    reader=csv.reader(DAQfile,delimiter=',')
    for row in reader:
       … calculate stuff…

with open('results.csv','w',newline='') as myfile:
    mywriter = csv.writer(myfile)
    …write stuff…
根据到目前为止的评论,添加一些细节: 该程序计算“瞬时功率”移动平均值的峰值。csv文件中的数据可以这样描述,其中“col”表示列,V表示电压,I表示电流:col1=time,col2=V1,col3=I1,col4=V2,col5=I2,依此类推,直到col11=V10,col12=I10。因此,每一行表示DAQ采集的数据样本。 瞬时功率为Pi=V1*I1+V2*I2+…+V11*I11 为了一次计算10000行以上的移动平均数,我构建了一个缓冲区(用buffer=[0]*10000初始化)。此缓冲区将存储10000个连续行的Pi,并在每次csv.reader移动到下一行时更新。缓冲器的工作原理与移位寄存器完全相同。 通过这种方式,内存使用是不重要的(已验证)。总之,计算包括乘法、加法、min(a、b)函数(用于检测移动平均值的峰值)和del/append(用于刷新缓冲区)。移动平均线本身也是迭代的,类似于newavg=oldavg+(newlast-oldfirst)/bufsize。 我的想法是,当我知道大多数尾随数字都是垃圾时,让Python处理所有这些小数是没有任何意义的。
忘了提及来自DAQ的csv文件大小略低于1Gb。

请使用DyZ的注释。如果有一种方法可以加快计算速度,(即分别使用>进行乘法或除法)。如果第二个操作数或被除数是2的幂,则应使用它。 例如:

>22*16
352
>>>22是的,有一种使用方法。首先,有大量向量/向量操作,可以用一个命令执行

a = b + c
将两个向量有效求和

第二,这是您问题的答案,您可以指定4字节浮点类型,大大减少内存需求并提高速度

您应该直接使用

from numpy import genfromtxt
data = genfromtxt('datafile.csv', dtype=numpy.float32, delimiter=',')
...
数据
将由标准32位浮点组成,精度约为7位

CSV文件可以通过部件/束读取

numpy.genfromtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None,
skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None,
usecols=None, names=None, excludelist=None, deletechars=None, replace_space='_',
autostrip=False, case_sensitive=True, defaultfmt='f%i',
unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None,
encoding='bytes')
numpy.genfromtxt(fname,dtype=,comments=“#”,delimiter=None,
跳过页眉=0,跳过页脚=0,转换器=无,缺少值=无,填充值=无,
usecols=None,names=None,excludelist=None,deletechars=None,replace_space='''',
autostrip=False,区分大小写=True,defaultfmt='f%i',
解包=无,使用掩码=假,松散=真,无效上升=真,最大行数=无,
编码(字节)

这里是完整的参数列表。如果代码> Max Surns被设置为“10”,则只读取10行。默认值是读取整个文件。您可以通过跳过一些初始记录来读取文件中间的任何东西,通过<代码> SkIPHead < /Cord>选项> < /P>。也许您应该查看计算的性质,而不是精度。许多数字。ric操作可以通过使用NumPy大大加快。我不这么认为,即使你可以,我也高度怀疑它会显著提高性能,因为

float
s已经非常有效。你确定精度是瓶颈吗?尝试将所有数字转换为
int
s,然后首先进行基准测试。如果是这样的话如果您的值是
float
类型,那么这些值是处理器中浮点单元的本机格式,因此切换到类似7位精度的小数将使速度大大降低,而不是加快。(除非您实际使用的是16位
decimal.decimal
值,在这种情况下,切换到
float
将比7位
decimal
s更快)如果您无法更改算法,通常关键是(a)通过使用numpy数组、使用numba.jit、用PyPy而不是CPython运行脚本、用Cython(或C/C++/Rust/whatever)等重写该内部循环来加速内部循环,和/或(b)通过使用multiprocessing/concurrent.futures(或有时是(C))并行化外部循环使用numba+CUDA来加快速度,并通过将它们推到GPU上实现更大的并行化)。首先测量时间花在哪里,如(如果没有测量,我想这是CVS解析和编写)另外,不要只考虑微优化,还要考虑所有级别的并行化:矢量化、多线程、多处理。NumPy、PySpark等可以帮助您完成这些。这很有趣,但这不会一次加载整个csv文件吗?我说的是1Gb。我使用的是csv.reader,因为它是逐行处理的,使用m最小内存使用量。@NP1请检查更新。坦率地说,如果您正在研究任何类型的数字(DAQ)处理,请检查更新
numpy.genfromtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None,
skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None,
usecols=None, names=None, excludelist=None, deletechars=None, replace_space='_',
autostrip=False, case_sensitive=True, defaultfmt='f%i',
unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None,
encoding='bytes')