уменьшить точность расчетов, чтобы ускорить выполнение - PullRequest
0 голосов
/ 25 мая 2018

У меня есть система сбора данных, которая проводит измерения в течение нескольких минут и генерирует CSV-файл с 10 миллионами строк и 10 столбцами.Затем я импортирую этот CSV-файл в Python (csv.reader), выполняю ряд операций с полученными числовыми данными (но «только» 10000 строк за раз, в противном случае память компьютера будет перегружена).В конце я экспортирую результаты в другой намного меньший файл csv (csv.writer).Проблема в том, что время выполнения очень длинное, и я хочу ускорить его.Когда я открываю исходный файл csv с помощью Блокнота, я вижу, что числа имеют до 16 цифр, например, 0,0015800159870059, 12.0257771094508 и т. Д. Я знаю, что точность DAQ в лучшем случае составляет 0,1%, и большинство последних цифр являются шумом.Существует ли элегантный способ заставить Python работать глобально с 7-8 цифрами от начала до конца, чтобы ускорить вычисления?Я знаю о распространении ошибок, и я собираюсь попробовать различные настройки для количества цифр, чтобы увидеть, что является оптимальным.Обратите внимание, что мне недостаточно создать временный CSV-файл с «усеченными» данными (например, содержащий 0,0015800, 12,0257771 и т. Д.) И просто импортировать их в 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 = время, col2 = V1, col3 = I1, col4 = V2, col5 = I2 и так далее доcol11 = V10, col12 = I10.Таким образом, каждая строка представляет выборку данных, взятую DAQ.Мгновенная мощность равна Pi = V1 * I1 + V2 * I2 + ... + V11 * I11. Чтобы рассчитать скользящее среднее по 10000 строкам за раз, я построил буфер (инициализированный с помощью Buffer = [0] * 10000).Этот буфер будет хранить Pi для 10000 последовательных строк и будет обновляться каждый раз, когда csv.reader переходит к следующей строке.Буфер работает точно так же, как регистр сдвига.Таким образом, использование памяти незначительно (проверено).Таким образом, вычисления представляют собой умножения, сложения, функцию min (a, b) (для обнаружения пика скользящей средней) и del / append для обновления буфера.Само скользящее среднее тоже итеративно, что-то вроде newavg = oldavg + (newlast-oldfirst) / bufsize.Я думаю, что нет никакого смысла позволять Python работать со всеми этими десятичными знаками, когда я знаю, что большинство конечных цифр - мусор.Забыл упомянуть, что размер файла CSV, поступающего от DAQ, составляет чуть менее 1 ГБ.

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Да, есть способ - используйте NumPy .Во-первых, существует множество векторных / векторных операций, которые можно выполнить с помощью одной команды

a = b + c

эффективно суммирует два вектора.

Во-вторых, ответ на ваш вопрос, выможет указывать 4-байтовый тип с плавающей запятой, значительно уменьшая требования к памяти и увеличивая скорость.

Вы должны читать ваш файл напрямую, используя

from numpy import genfromtxt
data = genfromtxt('datafile.csv', dtype=numpy.float32, delimiter=',')
...

data, составленный из стандартных 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')

вот полный список параметров.Если max_rows установлено, скажем, 10, будут прочитаны только 10 строк.По умолчанию читается весь файл.Вы можете прочитать что-нибудь в середине файлов, пропустив некоторые начальные записи, используя опцию skip_header.

0 голосов
/ 25 мая 2018

Используйте комментарий DyZ.если есть способ ускорить вычисления (т. е. использовать << или >> для умножения или деления соответственно, если второй операнд или дивиденд равен степени 2, вы должны взять его. пример:

>>> 22 * 16
352
>>> 22 << 4
352

В этом сценарии я проделал точно такую ​​же операцию с незначительным уменьшением времени. Однако, если это будет равняться 100 триллионам вычислений, разница будет гораздо более заметной.

...