#python-3.x #matplotlib #plot #garbage-collection
#python-3.x #pandas #matplotlib
Вопрос:
Я пытаюсь прочитать большие .trc
файлы осциллографа и отобразить их. Построение одного файла работает, но как только я помещаю скрипт в цикл, пытаюсь отобразить все файлы (по 1 файлу в цикл) Я получаю MemoryError
.
Код:
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import readTrc #external file, same location as script
foldername = 'trc_folder'
folder = os.listdir(foldername)
path = os.path.dirname(os.path.realpath(__file__))
for filenumber, i in enumerate(folder):
trc = path '/' foldername '/' i
print('reading trc file ' str(filenumber))
datX, datY, m = readTrc.readTrc(trc)
srx, sry = pd.Series(datX * 1000), pd.Series(datY * 1000)
df_oszi = pd.concat([srx, sry], axis = 1)
df_oszi.set_index(0, inplace = True)
#ERROR APPEARS with xticks argument
#removing xticks does not help, because then errorpath changes to
#/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py
df_oszi.plot(grid = 1,
color = 'blue',
linewidth = 0.5,
figsize = (9,5),
legend = False,
xticks = np.arange(df_oszi.index[0], df_oszi.index[-1], 1))
print('plotting file ' str(filenumber))
plt.savefig('Plot_' str(filenumber) '.png', dpi = 300)
Похоже, проблема во внешнем модуле readTrc
. Мне потребовалось довольно много времени, чтобы разобраться в этом, потому что python выдавал ошибки вокруг Matplotlib
и Pandas
вместо readTrc
, что, похоже, является неофициальным сценарием для чтения .trc
файлов. Я нашел это в сети, когда искал способ чтения .trc
файлов на python. Если вы знаете лучший способ чтения файлов осциллографа, пожалуйста, дайте мне знать.
Я заархивировал все, что вам нужно для выполнения скрипта, в эту папку: папка
(Он довольно большой, 582MB
потому что каждый .trc
файл имеет примерно 200MB
размер) Внутри вы найдете скрипт, папку с .trc
файлами и внешний файл (модуль) python, readTrc
который требуется для чтения .trc
файлов. Выполнение скрипта должно отображать первый файл, но выбрасывать MemoryError
при построении второго, по крайней мере, на моей машине Ubuntu. Меня смущает то, что я получаю это только MemoryError
в Ubuntu (18.04), а не в Windows 10.
Я был бы признателен за помощь, чтобы я мог продолжить свой проект. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.
Редактировать:
Единственная загрузка для readTrc.py
Единственная загрузка для Script.py
print(type(datX))
ВОЗВРАТ:
<class 'numpy.ndarray'>
печать datX
возвращает объект с 50 миллионами значений:
[-0.005 -0.005 -0.005 ... 0.005 0.005 0.005]
они округляются по print()
функции и являются:
-0.004999999906663635
-0.004999999806663634
-0.004999999706663633
-0.004999999606663631
-0.00499999950666363
Edit 2:
Чтобы запустить код с новой версией readTrc
, внесите эти изменения:
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import readTrc
foldername = 'trc_folder'
folder = os.listdir(foldername)
path = os.path.dirname(os.path.realpath(__file__))
for filenumber, i in enumerate(folder):
trc = path '/' foldername '/' i
print('reading trc file ' str(filenumber))
datX, datY, d = readTrc.Trc().open(trc)
srx, sry = pd.Series(datX * 1000), pd.Series(datY * 1000)
df_oszi = pd.concat([srx, sry], axis = 1)
df_oszi.set_index(0, inplace = True)
df_oszi.plot(grid = 1,
color = 'blue',
linewidth = 0.5,
figsize = (9,5),
legend = False,
xticks = np.arange(df_oszi.index[0], df_oszi.index[-1], 1))
print('plotting file ' str(filenumber))
plt.savefig('Plot_' str(filenumber) '.png', dpi = 300)
Ошибка памяти:
Traceback (most recent call last):
File "/home/artur/Desktop/zip_original/Script.py", line 27, in <module>
xticks = np.arange(df_oszi.index[0], df_oszi.index[-1], 1))
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 2941, in __call__
sort_columns=sort_columns, **kwds)
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 1977, in plot_frame
**kwds)
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 1804, in _plot
plot_obj.generate()
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 260, in generate
self._make_plot()
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 985, in _make_plot
**kwds)
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 1001, in _plot
lines = MPLPlot._plot(ax, x, y_values, style=style, **kwds)
File "/usr/local/lib/python3.6/dist-packages/pandas/plotting/_core.py", line 615, in _plot
return ax.plot(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/matplotlib/__init__.py", line 1805, in inner
return func(ax, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_axes.py", line 1604, in plot
self.add_line(line)
File "/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_base.py", line 1891, in add_line
self._update_line_limits(line)
File "/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_base.py", line 1913, in _update_line_limits
path = line.get_path()
File "/usr/local/lib/python3.6/dist-packages/matplotlib/lines.py", line 945, in get_path
self.recache()
File "/usr/local/lib/python3.6/dist-packages/matplotlib/lines.py", line 649, in recache
self._xy = np.column_stack(np.broadcast_arrays(x, y)).astype(float)
MemoryError
Редактировать 3:
Выборка набора данных, похоже, уменьшает значение данных. Это примеры одного и того же набора данных с sampling = 1, sampling = 10, sampling = 100
srx, sry = pd.Series(datX[::sampling] * 1000), pd.Series(datY[::sampling] * 1000)
Причиной этого является чрезвычайно короткий период импульса волн сверхвысокой частоты (УВЧ). Каждый импульс может состоять только из нескольких значений данных. Если вы укажете количество учитываемых значений, это приведет к большой потере данных. Хотя это решение заставляет код работать, оно также значительно снижает ценность данных.
Комментарии:
1. Не могли бы вы также загрузить только
readTrc.py
файл? Я действительно не хочу загружать ~ 600 МБ для этого 🙂 Помимо этого: что возвращаетprint(type(datX))
? Этоlist
,numpy.ndarray
,dataframe
? Вы пробовали использовать этот модуль readTrc ?2. Пожалуйста, найдите запрошенную информацию в разделе Редактировать
3. Что касается
readTrc module
: кажется, что я использую старую версию этого файла с 2017 года. Я просто попытался заменить старый на новый, но, похоже, для его работы требуются дополнительные усилия. Я попытаюсь запустить скрипт с новой версией.4. Хорошо, итак, если
datX=[1,2,3]
это действительно список (к сожалению, вы не опубликовали возвратprint(type(datX))
), тоprint(10*a)
выдаст вам[1, 2, 3, 1, 2, 3,…..]
, то есть список, умноженный на десять. Вероятно, это не то, что вы хотите, поэтому сначала попробуйте сделать его массивом numpy, т.Е.datX=np.array(datX)
иdatY=np.array(datY)
сразу после вызоваreadTrc.readTrc()
5. Извините, я перепутал
print()
сprint(type())
. Я добавил его в раздел » Редактировать «. На самом деле это<class 'numpy.ndarray'>
Ответ №1:
О, вау, я не мог видеть дерево за деревьями, как говорится. Вы пытаетесь построить слишком много точек данных (т. 100000002
Я думаю, что это около 4 км бумаги, напечатанной со скоростью 600 точек на дюйм), что может быть разрешено либо путем выборки:
sampling=100
srx, sry = pd.Series(datX[::sampling] * 1000), pd.Series(datY[::sampling] * 1000)
или выборочным изучением определенных диапазонов:
srx, sry = pd.Series(datX[0:50000] * 1000), pd.Series(datY[0:50000] * 1000)
или комбинация обоих.
Комментарии:
1. Спасибо вам за ваши усилия до сих пор. Вы мне очень помогли. Хотя, боюсь, я не могу реализовать это решение. Пожалуйста, смотрите раздел Редактировать 3 .
2. Я боюсь, что вы путаете видимые функции с присутствующими функциями . Становятся ли ваши короткие импульсы видимыми на графике, зависит от размера вашего рисунка / разрешения / масштабирования. Вам нужно найти способ минимизировать объем данных, возможно, с помощью БПФ сигнала или путем отбрасывания значений, где, например, np.abs (y)<=1.
Ответ №2:
Это заняло довольно много времени, но мне удалось взять MemoryError
под контроль. Мне приходилось не только ставить gc.collect()
в конце каждого цикла, но и plt.close()
. Только тогда ошибки прекратятся. Извините за путаницу. Я многому научился из этого.