Есть ли лучший способ пересмотреть временные ряды, хранящиеся в двоичных файлах в Python? - PullRequest
0 голосов
/ 23 октября 2018

Я хотел бы пересчитать временные ряды, хранящиеся в двоичных файлах int32, используя Python.Я записал функцию, которая делает свое дело;Вот упрощенная версия моей функции:

import numpy as np
import scipy.signal as signal

def resampleData(fileName_in,fileName_out,new_number_of_samples) 

    fIn = open(fileName_in, 'rb')
    data_in = np.fromfile(fIn, dtype="int32", count=-1, sep="")  
    fIn.close()

    data_out=signal.resample(data_in,new_number_of_samples).astype('int32')

    fOut = open(fileName_out, 'wb')
    data_out.tofile(fOut,sep="")
    fOut.close()

    return

Когда я работаю с большими файлами, мой код выполняется долго, что заставляет меня задуматься, есть ли лучшее решение.Например, есть ли встроенный метод, позволяющий напрямую пересчитывать временные ряды, хранящиеся в двоичных файлах, без необходимости записывать их в ndarray?

Большое спасибо за вашу помощь!

1 Ответ

0 голосов
/ 24 октября 2018

Я не думаю, что здесь возникает проблема с вводом-выводом, поскольку даже для этого большого массива:

np.empty(1000000000, 'i').tofile('abc.bin')
np.fromfile('abc.bin', 'i')

Для его чтения требуется всего

1.18 s ± 26.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

.Если вы настаиваете, вы можете использовать memmap:

np.memmap('abc.bin', 'i')

, который занимает «незначительное время» для «загрузки», но все равно придется выполнить IO позже:

5.6 µs ± 433 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

С другойстороны, если под повторной выборкой вы имеете в виду понижающую выборку, вы можете использовать метод memmap, описанный выше, и напрямую сохранить фрагмент массива оригиналов, например

memmap_result[::2].tofile('xxx')

, который уменьшит выборки вдвое.

Если вам нужна нецелочисленная пошаговая выборка или повышающая выборка, и, что более важно, вам подходит метод ближайшего соседа, вы можете использовать необычную индексацию, например:

memmap_result[np.linspace(0, len(memmap_result), num_samples).astype('i')]

, которая также должнаБыть быстрым.

В других случаях вам может потребоваться поискать другие алгоритмы повторной выборки.Я вижу, scipy.signal.resample использует преобразование Фурье, которое должно быть довольно быстрым и стабильным.Вы можете использовать еще более быстрые алгоритмы, такие как линейная интерполяция и т. Д. Но это может повлиять на качество повторной выборки.

...